@@ -27,13 +27,14 @@ namespace wi
2727 Shader wireframePS;
2828 Shader oceanSurfPS;
2929 Shader oceanSurfPS_envmap;
30+ Shader oceanSurfPS_shadowmap;
3031
3132 RasterizerState rasterizerState;
3233 RasterizerState wireRS;
33- DepthStencilState depthStencilState, depthStencilState_occlusionTest;
34- BlendState blendState, blendState_occlusionTest;
34+ DepthStencilState depthStencilState, depthStencilState_occlusionTest, depthStencilState_shadowmap ;
35+ BlendState blendState, blendState_occlusionTest, blendState_shadowmap ;
3536
36- PipelineState PSO , PSO_envmap, PSO_wire, PSO_occlusionTest;
37+ PipelineState PSO , PSO_envmap, PSO_shadowmap, PSO_wire, PSO_occlusionTest;
3738 Texture perlinTex;
3839
3940 void LoadShaders ()
@@ -46,6 +47,7 @@ namespace wi
4647
4748 wi::renderer::LoadShader (ShaderStage::PS , oceanSurfPS, " oceanSurfacePS.cso" );
4849 wi::renderer::LoadShader (ShaderStage::PS , oceanSurfPS_envmap, " oceanSurfacePS_envmap.cso" );
50+ wi::renderer::LoadShader (ShaderStage::PS , oceanSurfPS_shadowmap, " oceanSurfacePS_shadowmap.cso" );
4951 wi::renderer::LoadShader (ShaderStage::PS , wireframePS, " oceanSurfaceSimplePS.cso" );
5052
5153
@@ -63,8 +65,15 @@ namespace wi
6365 desc.ps = &oceanSurfPS_envmap;
6466 device->CreatePipelineState (&desc, &PSO_envmap);
6567
68+ desc.ps = &oceanSurfPS_shadowmap;
69+ desc.bs = &blendState_shadowmap;
70+ desc.dss = &depthStencilState_shadowmap;
71+ device->CreatePipelineState (&desc, &PSO_shadowmap);
72+
73+ desc.bs = &blendState;
6674 desc.ps = &wireframePS;
6775 desc.rs = &wireRS;
76+ desc.dss = &depthStencilState;
6877 device->CreatePipelineState (&desc, &PSO_wire);
6978
7079 desc.ps = {};
@@ -541,6 +550,64 @@ namespace wi
541550 device->EventEnd (cmd);
542551 }
543552
553+ void Ocean::RenderForShadowmap (CommandList cmd) const
554+ {
555+ GraphicsDevice* device = wi::graphics::GetDevice ();
556+
557+ device->EventBegin (" Ocean Rendering into shadow map" , cmd);
558+
559+ const uint2 dim = uint2 (64 , 64 );
560+ const uint index_count = dim.x * dim.y * 6 ;
561+ const uint64_t indexbuffer_required_size = index_count * sizeof (uint16_t );
562+ static std::mutex locker;
563+ locker.lock (); // in case two threads draw the ocean the same time, index buffer creation must be locked
564+ if (indexBuffer_shadowmap.GetDesc ().size != indexbuffer_required_size)
565+ {
566+ wi::vector<uint16_t > index_data (index_count);
567+ size_t counter = 0 ;
568+ for (uint16_t x = 0 ; x < dim.x - 1 ; x++)
569+ {
570+ for (uint16_t y = 0 ; y < dim.y - 1 ; y++)
571+ {
572+ uint16_t lowerLeft = x + y * dim.x ;
573+ uint16_t lowerRight = (x + 1 ) + y * dim.x ;
574+ uint16_t topLeft = x + (y + 1 ) * dim.x ;
575+ uint16_t topRight = (x + 1 ) + (y + 1 ) * dim.x ;
576+
577+ index_data[counter++] = topLeft;
578+ index_data[counter++] = lowerLeft;
579+ index_data[counter++] = lowerRight;
580+
581+ index_data[counter++] = topLeft;
582+ index_data[counter++] = lowerRight;
583+ index_data[counter++] = topRight;
584+ }
585+ }
586+
587+ GPUBufferDesc desc;
588+ desc.bind_flags = BindFlag::INDEX_BUFFER ;
589+ desc.size = indexbuffer_required_size;
590+ device->CreateBuffer (&desc, index_data.data (), &indexBuffer_shadowmap);
591+ device->SetName (&indexBuffer_shadowmap, " Ocean::indexBuffer_shadowmap" );
592+ }
593+ locker.unlock ();
594+
595+ device->BindPipelineState (&PSO_shadowmap, cmd);
596+
597+ OceanCB cb = GetOceanCBAtDim (params, dim);
598+ device->BindDynamicConstantBuffer (cb, CB_GETBINDSLOT (OceanCB), cmd);
599+
600+ device->BindResource (&displacementMap, 0 , cmd);
601+ device->BindResource (&gradientMap, 1 , cmd);
602+ device->BindResource (&perlinTex, 2 , cmd);
603+
604+ device->BindIndexBuffer (&indexBuffer_shadowmap, IndexBufferFormat::UINT16 , 0 , cmd);
605+
606+ device->DrawIndexedInstanced (index_count, 1 , 0 , 0 , 0 , cmd);
607+
608+ device->EventEnd (cmd);
609+ }
610+
544611 void Ocean::Render (const CameraComponent& camera, CommandList cmd) const
545612 {
546613 GraphicsDevice* device = wi::graphics::GetDevice ();
@@ -637,6 +704,7 @@ namespace wi
637704
638705 depth_desc.depth_write_mask = DepthWriteMask::ZERO ;
639706 depthStencilState_occlusionTest = depth_desc;
707+ depthStencilState_shadowmap = depth_desc;
640708
641709 BlendState blend_desc;
642710 blend_desc.alpha_to_coverage_enable = false ;
@@ -654,6 +722,18 @@ namespace wi
654722 blend_desc.render_target [0 ].blend_enable = false ;
655723 blendState_occlusionTest = blend_desc;
656724
725+ blend_desc.render_target [0 ].src_blend = Blend::ZERO ;
726+ blend_desc.render_target [0 ].dest_blend = Blend::SRC_COLOR ;
727+ blend_desc.render_target [0 ].blend_op = BlendOp::ADD ;
728+ blend_desc.render_target [0 ].src_blend_alpha = Blend::ONE ;
729+ blend_desc.render_target [0 ].dest_blend_alpha = Blend::ONE ;
730+ blend_desc.render_target [0 ].blend_op_alpha = BlendOp::MAX ;
731+ blend_desc.render_target [0 ].blend_enable = true ;
732+ blend_desc.render_target [0 ].render_target_write_mask = ColorWrite::ENABLE_ALL ;
733+ blend_desc.alpha_to_coverage_enable = false ;
734+ blend_desc.independent_blend_enable = false ;
735+ blendState_shadowmap = blend_desc;
736+
657737
658738 static wi::eventhandler::Handle handle = wi::eventhandler::Subscribe (wi::eventhandler::EVENT_RELOAD_SHADERS , [](uint64_t userdata) { LoadShaders (); wi::fftgenerator::LoadShaders (); });
659739
0 commit comments