GpuFftPS::GpuFftPS(uint32_t width, uint32_t height, bool forward) : width_(width), height_(height), forward_(forward) { BOOST_ASSERT(0 == (width_ & (width_ - 1))); BOOST_ASSERT(0 == (height_ & (height_ - 1))); log_x_ = static_cast<uint32_t>(log(static_cast<float>(width_)) / log(2.0f)); log_y_ = static_cast<uint32_t>(log(static_cast<float>(height_)) / log(2.0f)); lookup_i_wr_wi_x_tex_.resize(log_x_); lookup_i_wr_wi_y_tex_.resize(log_y_); std::vector<half> lookup_i_wr_wi_x(log_x_ * width_ * 4); std::vector<half> lookup_i_wr_wi_y(log_y_ * height_ * 4); this->CreateButterflyLookups(lookup_i_wr_wi_x, log_x_, width_); this->CreateButterflyLookups(lookup_i_wr_wi_y, log_y_, height_); RenderFactory& rf = Context::Instance().RenderFactoryInstance(); half* ptr = &lookup_i_wr_wi_x[0]; for (uint32_t i = 0; i < log_x_; ++ i) { ElementInitData init_data; init_data.data = ptr; init_data.row_pitch = width_ * sizeof(half) * 4; init_data.slice_pitch = init_data.row_pitch; lookup_i_wr_wi_x_tex_[i] = rf.MakeTexture2D(width_, 1, 1, 1, EF_ABGR16F, 1, 0, EAH_GPU_Read | EAH_Immutable, &init_data); ptr += width_ * 4; } ptr = &lookup_i_wr_wi_y[0]; for (uint32_t i = 0; i < log_y_; ++ i) { ElementInitData init_data; init_data.data = ptr; init_data.row_pitch = sizeof(half) * 4; init_data.slice_pitch = init_data.row_pitch * height_; lookup_i_wr_wi_y_tex_[i] = rf.MakeTexture2D(1, height_, 1, 1, EF_ABGR16F, 1, 0, EAH_GPU_Read | EAH_Immutable, &init_data); ptr += height_ * 4; } tmp_real_tex_[0] = rf.MakeTexture2D(width_, height_, 1, 1, EF_ABGR32F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); tmp_real_tex_[1] = rf.MakeTexture2D(width_, height_, 1, 1, EF_ABGR32F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); tmp_imag_tex_[0] = rf.MakeTexture2D(width_, height_, 1, 1, EF_ABGR32F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); tmp_imag_tex_[1] = rf.MakeTexture2D(width_, height_, 1, 1, EF_ABGR32F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); fft_x_pp_ = SyncLoadPostProcess("FFT.ppml", "fft_x"); fft_y_pp_ = SyncLoadPostProcess("FFT.ppml", "fft_y"); }
void MultiResSILLayer::RSM(TexturePtr const & rt0_tex, TexturePtr const & rt1_tex, TexturePtr const & depth_tex) { std::string RSM2VPLsSpotName = "RSM2VPLsSpot"; rsm_texs_[0] = rt0_tex; rsm_texs_[1] = rt1_tex; rsm_depth_tex_ = depth_tex; rsm_to_vpls_pps_[LightSource::LT_Spot] = SyncLoadPostProcess("RSM2VPLs.ppml", RSM2VPLsSpotName); rsm_to_vpls_pps_[LightSource::LT_Spot]->InputPin(0, rsm_texs_[0]); rsm_to_vpls_pps_[LightSource::LT_Spot]->InputPin(1, rsm_texs_[1]); rsm_to_vpls_pps_[LightSource::LT_Spot]->InputPin(2, rsm_depth_tex_); rsm_to_vpls_pps_[LightSource::LT_Spot]->InputPin(3, rsm_depth_derivative_tex_); rsm_to_vpls_pps_[LightSource::LT_Spot]->OutputPin(0, vpl_tex_); RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderDeviceCaps const & caps = rf.RenderEngineInstance().DeviceCaps(); ElementFormat fmt; if (caps.rendertarget_format_support(EF_GR32F, 1, 0)) { fmt = EF_GR32F; } else if (caps.rendertarget_format_support(EF_ABGR32F, 1, 0)) { fmt = EF_ABGR32F; } else if (caps.rendertarget_format_support(EF_GR16F, 1, 0)) { fmt = EF_GR16F; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_ABGR16F, 1, 0)); fmt = EF_ABGR16F; } rsm_depth_derivative_tex_ = rf.MakeTexture2D(MIN_RSM_MIPMAP_SIZE, MIN_RSM_MIPMAP_SIZE, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); rsm_to_depth_derivate_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2DepthDerivate"); rsm_to_depth_derivate_pp_->InputPin(1, rsm_depth_tex_); rsm_to_depth_derivate_pp_->OutputPin(0, rsm_depth_derivative_tex_); float delta_x = 1.0f / rsm_depth_derivative_tex_->Width(0); float delta_y = 1.0f / rsm_depth_derivative_tex_->Height(0); float4 rsm_delta_offset(delta_x, delta_y, delta_x / 2, delta_y / 2); rsm_to_depth_derivate_pp_->SetParam(0, rsm_delta_offset); }
void RenderEngine::Stereo(StereoMethod method) { stereo_method_ = method; if (stereo_method_ != STM_None) { std::string pp_name; switch (stereo_method_) { case STM_ColorAnaglyph_RedCyan: pp_name = "stereoscopic_red_cyan"; break; case STM_ColorAnaglyph_YellowBlue: pp_name = "stereoscopic_yellow_blue"; break; case STM_ColorAnaglyph_GreenRed: pp_name = "stereoscopic_green_red"; break; case STM_HorizontalInterlacing: pp_name = "stereoscopic_hor_interlacing"; break; case STM_VerticalInterlacing: pp_name = "stereoscopic_ver_interlacing"; break; case STM_Horizontal: pp_name = "stereoscopic_horizontal"; break; case STM_Vertical: pp_name = "stereoscopic_vertical"; break; case STM_LCDShutter: pp_name = "stereoscopic_lcd_shutter"; break; case STM_OculusVR: pp_name = "stereoscopic_oculus_vr"; break; default: BOOST_ASSERT(false); break; } stereoscopic_pp_ = SyncLoadPostProcess("Stereoscopic.ppml", pp_name); } pp_chain_dirty_ = true; }
MultiResLayer::MultiResLayer() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); { rl_quad_ = rf.MakeRenderLayout(); rl_quad_->TopologyType(RenderLayout::TT_TriangleStrip); float3 pos[] = { float3(+1, +1, 1), float3(-1, +1, 1), float3(+1, -1, 1), float3(-1, -1, 1) }; ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(sizeof(pos)); init_data.slice_pitch = 0; init_data.data = &pos[0]; rl_quad_->BindVertexStream(rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data), make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); } gbuffer_to_depth_derivate_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2DepthDerivate"); depth_derivate_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "DepthDerivateMipMap"); gbuffer_to_normal_cone_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2NormalCone"); normal_cone_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "NormalConeMipMap"); RenderEffectPtr subsplat_stencil_effect = SyncLoadRenderEffect("MultiRes.fxml"); subsplat_stencil_tech_ = subsplat_stencil_effect->TechniqueByName("SetSubsplatStencil"); subsplat_cur_lower_level_param_ = subsplat_stencil_effect->ParameterByName("cur_lower_level"); subsplat_is_not_first_last_level_param_ = subsplat_stencil_effect->ParameterByName("is_not_first_last_level"); subsplat_depth_deriv_tex_param_ = subsplat_stencil_effect->ParameterByName("depth_deriv_tex"); subsplat_normal_cone_tex_param_ = subsplat_stencil_effect->ParameterByName("normal_cone_tex"); subsplat_depth_normal_threshold_param_ = subsplat_stencil_effect->ParameterByName("depth_normal_threshold"); subsplat_far_plane_param_ = subsplat_stencil_effect->ParameterByName("far_plane"); upsampling_pp_ = SyncLoadPostProcess("MultiRes.ppml", "Upsampling"); }
SDSMCascadedShadowLayer::SDSMCascadedShadowLayer() : frame_index_(0) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderDeviceCaps const & caps = rf.RenderEngineInstance().DeviceCaps(); cs_support_ = caps.cs_support && (caps.max_shader_model >= ShaderModel(5, 0)); if (cs_support_) { interval_buff_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Read | EAH_GPU_Write | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_GR32F); scale_buff_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Write | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_BGR32F); bias_buff_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Write | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_BGR32F); cascade_min_buff_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Read | EAH_GPU_Write | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_BGR32F); cascade_max_buff_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Read | EAH_GPU_Write | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_BGR32F); interval_buff_->Resize(MAX_NUM_CASCADES * sizeof(float2)); scale_buff_->Resize(MAX_NUM_CASCADES * sizeof(float3)); bias_buff_->Resize(MAX_NUM_CASCADES * sizeof(float3)); cascade_min_buff_->Resize(MAX_NUM_CASCADES * sizeof(float3)); cascade_max_buff_->Resize(MAX_NUM_CASCADES * sizeof(float3)); for (uint32_t i = 0; i < 2; ++ i) { interval_cpu_buffs_[i] = rf.MakeVertexBuffer(BU_Dynamic, EAH_CPU_Read, nullptr); scale_cpu_buffs_[i] = rf.MakeVertexBuffer(BU_Dynamic, EAH_CPU_Read, nullptr); bias_cpu_buffs_[i] = rf.MakeVertexBuffer(BU_Dynamic, EAH_CPU_Read, nullptr); interval_cpu_buffs_[i]->Resize(interval_buff_->Size()); scale_cpu_buffs_[i]->Resize(scale_buff_->Size()); bias_cpu_buffs_[i]->Resize(bias_buff_->Size()); } RenderEffectPtr effect = SyncLoadRenderEffect("CascadedShadow.fxml"); clear_z_bounds_tech_ = effect->TechniqueByName("ClearZBounds"); reduce_z_bounds_from_depth_tech_ = effect->TechniqueByName("ReduceZBoundsFromDepth"); compute_log_cascades_from_z_bounds_tech_ = effect->TechniqueByName("ComputeLogCascadesFromZBounds"); clear_cascade_bounds_tech_ = effect->TechniqueByName("ClearCascadeBounds"); reduce_bounds_from_depth_tech_ = effect->TechniqueByName("ReduceBoundsFromDepth"); compute_custom_cascades_tech_ = effect->TechniqueByName("ComputeCustomCascades"); interval_buff_param_ = effect->ParameterByName("interval_buff"); interval_buff_uint_param_ = effect->ParameterByName("interval_buff_uint"); interval_buff_read_param_ = effect->ParameterByName("interval_buff_read"); scale_buff_param_ = effect->ParameterByName("scale_buff"); bias_buff_param_ = effect->ParameterByName("bias_buff"); cascade_min_buff_uint_param_ = effect->ParameterByName("cascade_min_buff_uint"); cascade_max_buff_uint_param_ = effect->ParameterByName("cascade_max_buff_uint"); cascade_min_buff_read_param_ = effect->ParameterByName("cascade_min_buff_read"); cascade_max_buff_read_param_ = effect->ParameterByName("cascade_max_buff_read"); depth_tex_param_ = effect->ParameterByName("depth_tex"); num_cascades_param_ = effect->ParameterByName("num_cascades"); inv_depth_width_height_param_ = effect->ParameterByName("inv_depth_width_height"); near_far_param_ = effect->ParameterByName("near_far"); upper_left_param_ = effect->ParameterByName("upper_left"); xy_dir_param_ = effect->ParameterByName("xy_dir"); view_to_light_view_proj_param_ = effect->ParameterByName("view_to_light_view_proj"); light_space_border_param_ = effect->ParameterByName("light_space_border"); max_cascade_scale_param_ = effect->ParameterByName("max_cascade_scale"); } else { reduce_z_bounds_from_depth_pp_ = SyncLoadPostProcess("CascadedShadow.ppml", "reduce_z_bounds_from_depth"); reduce_z_bounds_from_depth_mip_map_pp_ = SyncLoadPostProcess("CascadedShadow.ppml", "reduce_z_bounds_from_depth_mip_map"); compute_log_cascades_from_z_bounds_pp_ = SyncLoadPostProcess("CascadedShadow.ppml", "compute_log_cascades_from_z_bounds"); interval_tex_ = rf.MakeTexture2D(MAX_NUM_CASCADES, 1, 1, 1, EF_GR16F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); for (uint32_t i = 0; i < 2; ++ i) { interval_cpu_texs_[i] = rf.MakeTexture2D(MAX_NUM_CASCADES, 1, 1, 1, EF_GR16F, 1, 0, EAH_CPU_Read, nullptr); } } }
// 建立渲染窗口 ///////////////////////////////////////////////////////////////////////////////// void RenderEngine::CreateRenderWindow(std::string const & name, RenderSettings& settings) { if (settings.stereo_method != STM_OculusVR) { stereo_separation_ = settings.stereo_separation; } this->DoCreateRenderWindow(name, settings); this->CheckConfig(settings); RenderDeviceCaps const & caps = this->DeviceCaps(); screen_frame_buffer_ = cur_frame_buffer_; uint32_t const screen_width = screen_frame_buffer_->Width(); uint32_t const screen_height = screen_frame_buffer_->Height(); float const screen_aspect = static_cast<float>(screen_width) / screen_height; if (!MathLib::equal(screen_aspect, static_cast<float>(settings.width) / settings.height)) { settings.width = static_cast<uint32_t>(settings.height * screen_aspect + 0.5f); } RenderFactory& rf = Context::Instance().RenderFactoryInstance(); pp_rl_ = rf.MakeRenderLayout(); pp_rl_->TopologyType(RenderLayout::TT_TriangleStrip); float2 pos[] = { float2(-1, +1), float2(+1, +1), float2(-1, -1), float2(+1, -1) }; GraphicsBufferPtr pp_pos_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, sizeof(pos), &pos[0]); pp_rl_->BindVertexStream(pp_pos_vb, std::make_tuple(vertex_element(VEU_Position, 0, EF_GR32F))); uint32_t const render_width = static_cast<uint32_t>(settings.width * default_render_width_scale_ + 0.5f); uint32_t const render_height = static_cast<uint32_t>(settings.height * default_render_height_scale_ + 0.5f); hdr_enabled_ = settings.hdr; if (settings.hdr) { hdr_pp_ = MakeSharedPtr<HDRPostProcess>(settings.fft_lens_effects); skip_hdr_pp_ = SyncLoadPostProcess("Copy.ppml", "copy"); } ppaa_enabled_ = settings.ppaa ? 1 : 0; gamma_enabled_ = settings.gamma; color_grading_enabled_ = settings.color_grading; if (settings.ppaa || settings.color_grading || settings.gamma) { for (size_t i = 0; i < 12; ++ i) { ldr_pps_[i] = SyncLoadPostProcess("PostToneMapping.ppml", "PostToneMapping" + boost::lexical_cast<std::string>(i)); } ldr_pp_ = ldr_pps_[ppaa_enabled_ * 4 + gamma_enabled_ * 2 + color_grading_enabled_]; } bool need_resize = false; if (!settings.hide_win) { need_resize = ((render_width != screen_width) || (render_height != screen_height)); resize_pps_[0] = SyncLoadPostProcess("Resizer.ppml", "bilinear"); resize_pps_[1] = MakeSharedPtr<BicubicFilteringPostProcess>(); float const scale_x = static_cast<float>(screen_width) / render_width; float const scale_y = static_cast<float>(screen_height) / render_height; float2 pos_scale; if (scale_x < scale_y) { pos_scale.x() = 1; pos_scale.y() = (scale_x * render_height) / screen_height; } else { pos_scale.x() = (scale_y * render_width) / screen_width; pos_scale.y() = 1; } for (size_t i = 0; i < 2; ++ i) { resize_pps_[i]->SetParam(0, pos_scale); } } for (int i = 0; i < 4; ++ i) { default_frame_buffers_[i] = screen_frame_buffer_; } RenderViewPtr ds_view; if (hdr_pp_ || ldr_pp_ || (settings.stereo_method != STM_None)) { ds_tex_ = this->ScreenDepthStencilTexture(); if (ds_tex_ && (screen_width == render_width) && (screen_height == render_height)) { ds_view = rf.Make2DDepthStencilRenderView(*ds_tex_, 0, 1, 0); } else { if (caps.texture_format_support(EF_D32F) || caps.texture_format_support(EF_D24S8) || caps.texture_format_support(EF_D16)) { ElementFormat fmt; if ((settings.depth_stencil_fmt != EF_Unknown) && caps.texture_format_support(settings.depth_stencil_fmt)) { fmt = settings.depth_stencil_fmt; } else { BOOST_ASSERT(caps.texture_format_support(EF_D16)); fmt = EF_D16; } ds_tex_ = rf.MakeTexture2D(render_width, render_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); ds_view = rf.Make2DDepthStencilRenderView(*ds_tex_, 0, 1, 0); } else { ElementFormat fmt; if ((settings.depth_stencil_fmt != EF_Unknown) && caps.rendertarget_format_support(settings.depth_stencil_fmt, 1, 0)) { fmt = settings.depth_stencil_fmt; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_D16, 1, 0)); fmt = EF_D16; } ds_view = rf.Make2DDepthStencilRenderView(render_width, render_height, fmt, 1, 0); } } } if (settings.stereo_method != STM_None) { mono_frame_buffer_ = rf.MakeFrameBuffer(); mono_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.texture_format_support(settings.color_fmt) && caps.rendertarget_format_support(settings.color_fmt, 1, 0)) { fmt = settings.color_fmt; } else { if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } } mono_tex_ = rf.MakeTexture2D(screen_width, screen_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); mono_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*mono_tex_, 0, 1, 0)); default_frame_buffers_[0] = default_frame_buffers_[1] = default_frame_buffers_[2] = mono_frame_buffer_; overlay_frame_buffer_ = rf.MakeFrameBuffer(); overlay_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; overlay_tex_ = rf.MakeTexture2D(screen_width, screen_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); overlay_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*overlay_tex_, 0, 1, 0)); RenderViewPtr screen_size_ds_view; if (need_resize) { screen_size_ds_view = rf.Make2DDepthStencilRenderView(screen_width, screen_height, ds_view->Format(), 1, 0); } else { screen_size_ds_view = ds_view; } overlay_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, screen_size_ds_view); } else { if (need_resize) { resize_frame_buffer_ = rf.MakeFrameBuffer(); resize_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } resize_tex_ = rf.MakeTexture2D(render_width, render_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); resize_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*resize_tex_, 0, 1, 0)); ElementFormat ds_fmt; if ((settings.depth_stencil_fmt != EF_Unknown) && caps.rendertarget_format_support(settings.depth_stencil_fmt, 1, 0)) { ds_fmt = settings.depth_stencil_fmt; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_D16, 1, 0)); ds_fmt = EF_D16; } resize_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, rf.Make2DDepthStencilRenderView(render_width, render_height, ds_fmt, 1, 0)); default_frame_buffers_[0] = default_frame_buffers_[1] = default_frame_buffers_[2] = resize_frame_buffer_; } } if (ldr_pp_) { ldr_frame_buffer_ = rf.MakeFrameBuffer(); ldr_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } ElementFormat fmt_srgb = MakeSRGB(fmt); if (caps.texture_format_support(fmt_srgb) && caps.rendertarget_format_support(fmt_srgb, 1, 0)) { fmt = fmt_srgb; } ldr_tex_ = rf.MakeTexture2D(render_width, render_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); ldr_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*ldr_tex_, 0, 1, 0)); ldr_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, ds_view); default_frame_buffers_[0] = default_frame_buffers_[1] = ldr_frame_buffer_; } if (hdr_pp_) { hdr_frame_buffer_ = rf.MakeFrameBuffer(); hdr_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.fp_color_support) { if (caps.texture_format_support(EF_B10G11R11F) && caps.rendertarget_format_support(EF_B10G11R11F, 1, 0)) { fmt = EF_B10G11R11F; } else { BOOST_ASSERT(caps.texture_format_support(EF_ABGR16F) && caps.rendertarget_format_support(EF_ABGR16F, 1, 0)); fmt = EF_ABGR16F; } } else { if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } ElementFormat fmt_srgb = MakeSRGB(fmt); if (caps.rendertarget_format_support(fmt_srgb, 1, 0)) { fmt = fmt_srgb; } } hdr_tex_ = rf.MakeTexture2D(render_width, render_height, 4, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write | EAH_Generate_Mips, nullptr); hdr_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*hdr_tex_, 0, 1, 0)); hdr_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, ds_view); default_frame_buffers_[0] = hdr_frame_buffer_; } this->BindFrameBuffer(default_frame_buffers_[0]); this->Stereo(settings.stereo_method); #ifndef KLAYGE_SHIP PerfProfiler& profiler = PerfProfiler::Instance(); hdr_pp_perf_ = profiler.CreatePerfRange(0, "HDR PP"); ldr_pp_perf_ = profiler.CreatePerfRange(0, "LDR PP"); resize_pp_perf_ = profiler.CreatePerfRange(0, "Resize PP"); stereoscopic_pp_perf_ = profiler.CreatePerfRange(0, "Stereoscopic PP"); #endif }
ProceduralTerrain::ProceduralTerrain() : HQTerrainRenderable(SyncLoadRenderEffect("ProceduralTerrain.fxml")) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); RenderDeviceCaps const & caps = re.DeviceCaps(); ElementFormat height_fmt; if (caps.pack_to_rgba_required) { if (caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { height_fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_ARGB8, 1, 0)); height_fmt = EF_ARGB8; } } else { if (caps.rendertarget_format_support(EF_R16F, 1, 0)) { height_fmt = EF_R16F; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_R32F, 1, 0)); height_fmt = EF_R32F; } } height_map_tex_ = rf.MakeTexture2D(COARSE_HEIGHT_MAP_SIZE, COARSE_HEIGHT_MAP_SIZE, 1, 1, height_fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); height_map_cpu_tex_ = rf.MakeTexture2D(height_map_tex_->Width(0), height_map_tex_->Height(0), 1, 1, height_map_tex_->Format(), 1, 0, EAH_CPU_Read, nullptr); ElementFormat gradient_fmt; if (EF_R16F == height_fmt) { gradient_fmt = EF_GR16F; } else if (EF_R32F == height_fmt) { gradient_fmt = EF_GR32F; } else { gradient_fmt = height_fmt; } gradient_map_tex_ = rf.MakeTexture2D(COARSE_HEIGHT_MAP_SIZE, COARSE_HEIGHT_MAP_SIZE, 1, 1, gradient_fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); gradient_map_cpu_tex_ = rf.MakeTexture2D(gradient_map_tex_->Width(0), gradient_map_tex_->Height(0), 1, 1, gradient_map_tex_->Format(), 1, 0, EAH_CPU_Read, nullptr); ElementFormat mask_fmt; if (caps.texture_format_support(EF_ABGR8)) { mask_fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8)); mask_fmt = EF_ARGB8; } mask_map_tex_ = rf.MakeTexture2D(COARSE_HEIGHT_MAP_SIZE, COARSE_HEIGHT_MAP_SIZE, 1, 1, mask_fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); mask_map_cpu_tex_ = rf.MakeTexture2D(mask_map_tex_->Width(0), mask_map_tex_->Height(0), 1, 1, mask_map_tex_->Format(), 1, 0, EAH_CPU_Read, nullptr); height_pp_ = SyncLoadPostProcess("ProceduralTerrain.ppml", "height"); gradient_pp_ = SyncLoadPostProcess("ProceduralTerrain.ppml", "gradient"); mask_pp_ = SyncLoadPostProcess("ProceduralTerrain.ppml", "mask"); height_pp_->OutputPin(0, height_map_tex_); gradient_pp_->InputPin(0, height_map_tex_); gradient_pp_->OutputPin(0, gradient_map_tex_); mask_pp_->InputPin(0, height_map_tex_); mask_pp_->InputPin(1, gradient_map_tex_); mask_pp_->OutputPin(0, mask_map_tex_); }
MultiResSILLayer::MultiResSILLayer() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); RenderDeviceCaps const & caps = re.DeviceCaps(); { rl_quad_ = rf.MakeRenderLayout(); rl_quad_->TopologyType(RenderLayout::TT_TriangleStrip); std::vector<float3> pos; std::vector<uint16_t> index; pos.push_back(float3(+1, +1, 1)); pos.push_back(float3(-1, +1, 1)); pos.push_back(float3(+1, -1, 1)); pos.push_back(float3(-1, -1, 1)); ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(pos.size() * sizeof(pos[0])); init_data.slice_pitch = 0; init_data.data = &pos[0]; rl_quad_->BindVertexStream(rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data), make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); } vpl_tex_ = rf.MakeTexture2D(VPL_COUNT, 4, 1, 1, EF_ABGR16F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); gbuffer_to_depth_derivate_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2DepthDerivate"); depth_derivate_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "DepthDerivateMipMap"); gbuffer_to_normal_cone_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2NormalCone"); normal_cone_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "NormalConeMipMap"); RenderEffectPtr subsplat_stencil_effect = SyncLoadRenderEffect("MultiRes.fxml"); subsplat_stencil_tech_ = subsplat_stencil_effect->TechniqueByName("SetSubsplatStencil"); subsplat_cur_lower_level_param_ = subsplat_stencil_effect->ParameterByName("cur_lower_level"); subsplat_is_not_first_last_level_param_ = subsplat_stencil_effect->ParameterByName("is_not_first_last_level"); subsplat_depth_deriv_tex_param_ = subsplat_stencil_effect->ParameterByName("depth_deriv_tex"); subsplat_normal_cone_tex_param_ = subsplat_stencil_effect->ParameterByName("normal_cone_tex"); subsplat_depth_normal_threshold_param_ = subsplat_stencil_effect->ParameterByName("depth_normal_threshold"); RenderEffectPtr vpls_lighting_effect = SyncLoadRenderEffect("VPLsLighting.fxml"); vpls_lighting_instance_id_tech_ = vpls_lighting_effect->TechniqueByName("VPLsLightingInstanceID"); vpls_lighting_no_instance_id_tech_ = vpls_lighting_effect->TechniqueByName("VPLsLightingNoInstanceID"); vpl_view_param_ = vpls_lighting_effect->ParameterByName("view"); vpl_proj_param_ = vpls_lighting_effect->ParameterByName("proj"); vpl_depth_near_far_invfar_param_ = vpls_lighting_effect->ParameterByName("depth_near_far_invfar"); vpl_light_pos_es_param_ = vpls_lighting_effect->ParameterByName("light_pos_es"); vpl_light_color_param_ = vpls_lighting_effect->ParameterByName("light_color"); vpl_light_falloff_param_ = vpls_lighting_effect->ParameterByName("light_falloff"); vpl_x_coord_param_ = vpls_lighting_effect->ParameterByName("x_coord"); vpl_gbuffer_tex_param_ = vpls_lighting_effect->ParameterByName("gbuffer_tex"); vpl_depth_tex_param_ = vpls_lighting_effect->ParameterByName("depth_tex"); *(vpls_lighting_effect->ParameterByName("vpls_tex")) = vpl_tex_; *(vpls_lighting_effect->ParameterByName("vpl_params")) = float2(1.0f / VPL_COUNT, 0.5f / VPL_COUNT); upsampling_pp_ = SyncLoadPostProcess("MultiRes.ppml", "Upsampling"); rl_vpl_ = SyncLoadModel("indirect_light_proxy.meshml", EAH_GPU_Read | EAH_Immutable, CreateModelFactory<RenderModel>(), CreateMeshFactory<StaticMesh>())->Mesh(0)->GetRenderLayout(); if (caps.instance_id_support) { rl_vpl_->NumInstances(VPL_COUNT); } }