Skip to content

Commit 83f09a8

Browse files
committed
ocean caustic for all light types
1 parent 8174073 commit 83f09a8

12 files changed

Lines changed: 184 additions & 31 deletions

WickedEngine/offlineshadercompiler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ wi::vector<ShaderEntry> shaders = {
236236
{"emittedparticlePS_soft_lighting", wi::graphics::ShaderStage::PS },
237237
{"oceanSurfacePS", wi::graphics::ShaderStage::PS },
238238
{"oceanSurfacePS_envmap", wi::graphics::ShaderStage::PS },
239+
{"oceanSurfacePS_shadowmap", wi::graphics::ShaderStage::PS },
239240
{"hairparticlePS", wi::graphics::ShaderStage::PS },
240241
{"hairparticlePS_simple", wi::graphics::ShaderStage::PS },
241242
{"hairparticlePS_prepass", wi::graphics::ShaderStage::PS },

WickedEngine/shaders/Shaders_SOURCE.vcxitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@
352352
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
353353
</FxCompile>
354354
<FxCompile Include="$(MSBuildThisFileDirectory)oceanSurfacePS_envmap.hlsl" />
355+
<FxCompile Include="$(MSBuildThisFileDirectory)oceanSurfacePS_shadowmap.hlsl" />
355356
<FxCompile Include="$(MSBuildThisFileDirectory)paintdecalPS.hlsl">
356357
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
357358
</FxCompile>

WickedEngine/shaders/Shaders_SOURCE.vcxitems.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,9 @@
11331133
<FxCompile Include="$(MSBuildThisFileDirectory)visibility_analyzeCS.hlsl">
11341134
<Filter>CS</Filter>
11351135
</FxCompile>
1136+
<FxCompile Include="$(MSBuildThisFileDirectory)oceanSurfacePS_shadowmap.hlsl">
1137+
<Filter>PS</Filter>
1138+
</FxCompile>
11361139
</ItemGroup>
11371140
<ItemGroup>
11381141
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop.h">

WickedEngine/shaders/lightingHF.hlsli

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -151,29 +151,7 @@ inline void light_directional(in ShaderEntity light, in Surface surface, inout L
151151
const half scattering = ComputeScattering(saturate(dot(L, -surface.V)));
152152
lighting.indirect.specular += scattering * light_color * (1 - surface.extinction) * (1 - sqr(1 - saturate(1 - surface.N.y)));
153153
#endif // LIGHTING_SCATTER
154-
155-
#ifndef WATER
156-
// On non-water surfaces there can be procedural caustic if it's under ocean:
157-
const ShaderOcean ocean = GetWeather().ocean;
158-
if (ocean.texture_displacementmap >= 0)
159-
{
160-
Texture2D displacementmap = bindless_textures[descriptor_index(ocean.texture_displacementmap)];
161-
float2 ocean_uv = surface.P.xz * ocean.patch_size_rcp;
162-
float3 displacement = displacementmap.SampleLevel(sampler_linear_wrap, ocean_uv, 0).xzy;
163-
float water_height = ocean.water_height + displacement.y;
164-
if (surface.P.y < water_height)
165-
{
166-
half3 caustic = texture_caustics.SampleLevel(sampler_linear_mirror, ocean_uv, 0).rgb;
167-
caustic *= sqr(saturate((water_height - surface.P.y) * 0.5)); // fade out at shoreline
168-
caustic *= light_color;
169-
lighting.indirect.diffuse += caustic;
170-
171-
// fade out specular at depth, it looks weird when specular appears under ocean from wetmap
172-
half water_depth = water_height - surface.P.y;
173-
lighting.direct.specular *= saturate(exp(-water_depth * 10));
174-
}
175-
}
176-
#endif // WATER
154+
177155
}
178156

179157
inline half attenuation_pointlight(in half dist2, in half range, in half range2)

WickedEngine/shaders/objectHF.hlsli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace APPEND_COVER
818818
{
819819
surface.albedo = lerp(surface.albedo, 0, wet); // darken color when wet
820820
surface.roughness = clamp(surface.roughness * saturate(sqr((1 - wet) * 2 - 1)), 0.01, 1); // decrease eoughness when wet, but only at shoreline, not deeper underwater (sand underwater shouldn't be shiny)
821+
surface.f0 = lerp(surface.f0, 0, wet); // decrease reflectance when wet (not shiny when fully underwater)
821822
surface.N = normalize(lerp(surface.N, input.nor, wet)); // blend to vertex normal when wet
822823
}
823824
#endif // OBJECTSHADER_USE_COMMON

WickedEngine/shaders/oceanSurfacePS.hlsl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ Texture2D<float4> texture_perlin : register(t2);
1515
[earlydepthstencil]
1616
float4 main(PSIn input) : SV_TARGET
1717
{
18+
#ifdef SHADOWMAPRENDERING
19+
float4 color = 1;
20+
color.rgb += texture_caustics.SampleLevel(sampler_linear_mirror, input.uv, 0).rgb;
21+
color.a = input.pos.z; // secondary depth
22+
return color;
23+
#else
24+
1825
ShaderCamera camera = GetCameraIndexed(input.cameraIndex);
1926
float lineardepth = camera.IsOrtho() ? ((1 - input.pos.z) * camera.z_far) : input.pos.w;
2027
half4 color = xOceanWaterColor;
@@ -223,5 +230,7 @@ float4 main(PSIn input) : SV_TARGET
223230
ApplyFog(dist, V, color);
224231

225232
return saturateMediump(color);
233+
234+
#endif // SHADOWMAPRENDERING
226235
}
227236

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SHADOWMAPRENDERING
2+
#include "oceanSurfacePS.hlsl"

WickedEngine/shaders/shadowHF.hlsli

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,7 @@ inline half3 sample_shadow(float2 uv, float cmp, float4 uv_clamping, half2 radiu
211211
#ifndef DISABLE_TRANSPARENT_SHADOWMAP
212212
// !Reminder: there is no dependency between sampling shadowatlas and shadowatlas_transparent, this has best performance!
213213
half4 transparent_shadow = texture_shadowatlas_transparent.SampleLevel(sampler_linear_clamp, sample_uv, 0);
214-
#ifdef TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
215214
if (transparent_shadow.a > cmp)
216-
#endif // TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
217215
{
218216
pcf *= transparent_shadow.rgb;
219217
}
@@ -278,9 +276,7 @@ inline half3 sample_shadow(float2 uv, float cmp, min16uint2 pixel)
278276
#ifndef DISABLE_TRANSPARENT_SHADOWMAP
279277
Texture2D<half4> texture_shadowatlas_transparent = bindless_textures_half4[descriptor_index(GetFrame().texture_shadowatlas_transparent_index)];
280278
half4 transparent_shadow = texture_shadowatlas_transparent.SampleLevel(sampler_linear_clamp, uv, 0);
281-
#ifdef TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
282279
if (transparent_shadow.a > cmp)
283-
#endif // TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
284280
{
285281
shadow *= transparent_shadow.rgb;
286282
}

WickedEngine/wiOcean.cpp

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

WickedEngine/wiOcean.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace wi
4444
void UpdateDisplacementMap(wi::graphics::CommandList cmd) const;
4545
void RenderForOcclusionTest(const wi::scene::CameraComponent& camera, wi::graphics::CommandList cmd) const;
4646
void RenderForCubemap(wi::graphics::CommandList cmd) const;
47+
void RenderForShadowmap(wi::graphics::CommandList cmd) const;
4748
void Render(const wi::scene::CameraComponent& camera, wi::graphics::CommandList cmd) const;
4849

4950
void CopyDisplacementMapReadback(wi::graphics::CommandList cmd) const;
@@ -102,5 +103,6 @@ namespace wi
102103
mutable wi::graphics::GPUBuffer indexBuffer;
103104
mutable wi::graphics::GPUBuffer indexBuffer_occlusionTest;
104105
mutable wi::graphics::GPUBuffer indexBuffer_cubemap;
106+
mutable wi::graphics::GPUBuffer indexBuffer_shadowmap;
105107
};
106108
}

0 commit comments

Comments
 (0)