diff --git a/binaries/data/mods/mod/shaders/effects/terrain_shadow_caster.xml b/binaries/data/mods/mod/shaders/effects/terrain_shadow_caster.xml
new file mode 100644
index 0000000000..6f00b3d098
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/effects/terrain_shadow_caster.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/mod/shaders/effects/terrain_silhouette_occluder.xml b/binaries/data/mods/mod/shaders/effects/terrain_silhouette_occluder.xml
new file mode 100644
index 0000000000..0ea95bf7b9
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/effects/terrain_silhouette_occluder.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/ps/CStrInternStatic.h b/source/ps/CStrInternStatic.h
index 99d007f790..d9e8e5300e 100644
--- a/source/ps/CStrInternStatic.h
+++ b/source/ps/CStrInternStatic.h
@@ -171,6 +171,8 @@ X(sunDir)
X(terrain_base)
X(terrain_blend)
X(terrain_decal)
+X(terrain_shadow_caster)
+X(terrain_silhouette_occluder)
X(terrain_solid)
X(tex)
X(texSize)
diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp
index 4d440e39f0..38e2f04394 100644
--- a/source/renderer/SceneRenderer.cpp
+++ b/source/renderer/SceneRenderer.cpp
@@ -317,7 +317,7 @@ void CSceneRenderer::RenderShadowMap(
const int cullGroup = CULL_SHADOWS_CASCADE_0 + cascade;
{
PROFILE("render patches");
- m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup, shadowsContext);
+ m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup, {});
}
{
@@ -739,7 +739,7 @@ void CSceneRenderer::RenderSilhouettes(
{
PROFILE("render patches");
- m->terrainRenderer.RenderPatches(deviceCommandContext, CULL_SILHOUETTE_OCCLUDER, contextOccluder);
+ m->terrainRenderer.RenderPatches(deviceCommandContext, CULL_SILHOUETTE_OCCLUDER, {});
}
{
diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp
index 9b545fd131..da1c8cd4a9 100644
--- a/source/renderer/TerrainRenderer.cpp
+++ b/source/renderer/TerrainRenderer.cpp
@@ -93,6 +93,8 @@ struct TerrainRendererInternals
/// Fancy water shader
CShaderTechniquePtr fancyWaterTech;
+ CShaderTechniquePtr shadowCasterTech, silhouettteOccluderTech;
+
CShaderTechniquePtr shaderTechniqueSolid, shaderTechniqueSolidDepthTest;
Renderer::Backend::IVertexInputLayout* overlayVertexInputLayout = nullptr;
@@ -150,6 +152,10 @@ void TerrainRenderer::Initialize()
m->waterSurfaceVertexInputLayout = CPatchRData::GetWaterSurfaceVertexInputLayout(false);
m->waterSurfaceWithDataVertexInputLayout = CPatchRData::GetWaterSurfaceVertexInputLayout(true);
m->waterShoreVertexInputLayout = CPatchRData::GetWaterShoreVertexInputLayout();
+
+ CShaderManager& shaderManager{g_Renderer.GetShaderManager()};
+ m->shadowCasterTech = shaderManager.LoadEffect(str_terrain_shadow_caster);
+ m->silhouettteOccluderTech = shaderManager.LoadEffect(str_terrain_silhouette_occluder);
}
void TerrainRenderer::SetSimulation(CSimulation2* simulation)
@@ -372,7 +378,24 @@ void TerrainRenderer::RenderPatches(
GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain patches");
- CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_terrain_solid, defines);
+ CShaderTechniquePtr solidTech;
+ switch (cullGroup)
+ {
+ case CSceneRenderer::CULL_SHADOWS_CASCADE_0: [[fallthrough]];
+ case CSceneRenderer::CULL_SHADOWS_CASCADE_1: [[fallthrough]];
+ case CSceneRenderer::CULL_SHADOWS_CASCADE_2: [[fallthrough]];
+ case CSceneRenderer::CULL_SHADOWS_CASCADE_3:
+ ENSURE(defines.GetMap().empty());
+ solidTech = m->shadowCasterTech;
+ break;
+ case CSceneRenderer::CULL_SILHOUETTE_OCCLUDER:
+ ENSURE(defines.GetMap().empty());
+ solidTech = m->silhouettteOccluderTech;
+ break;
+ default:
+ solidTech = g_Renderer.GetShaderManager().LoadEffect(str_terrain_solid, defines);
+ break;
+ }
deviceCommandContext->SetGraphicsPipelineState(
solidTech->GetGraphicsPipelineState());
deviceCommandContext->BeginPass();