diff --git a/WickedEngine/shaders/ShaderInterop_Weather.h b/WickedEngine/shaders/ShaderInterop_Weather.h index 83565c862..0c40f0306 100644 --- a/WickedEngine/shaders/ShaderInterop_Weather.h +++ b/WickedEngine/shaders/ShaderInterop_Weather.h @@ -276,9 +276,9 @@ struct ShaderOcean { float4 water_color; float water_height; - float patch_size; float patch_size_rcp; int texture_displacementmap; + int texture_gradientmap; }; struct ShaderWeather @@ -286,12 +286,14 @@ struct ShaderWeather float3 sun_color; float sun_energy; float3 sun_direction; - float sky_exposure; + uint most_important_light_index; float3 horizon; - float cloudiness; + float sky_exposure; float3 zenith; - float cloud_scale; + float cloudiness; float3 ambient; + float cloud_scale; + float3 padding; float cloud_speed; ShaderFog fog; diff --git a/WickedEngine/shaders/globals.hlsli b/WickedEngine/shaders/globals.hlsli index 53b10549f..bde5e2c13 100644 --- a/WickedEngine/shaders/globals.hlsli +++ b/WickedEngine/shaders/globals.hlsli @@ -505,6 +505,16 @@ inline float3 reconstruct_position(in float2 uv, in float z) return reconstruct_position(uv, z, GetCamera().inverse_view_projection); } +// Caustic pattern from: https://www.shadertoy.com/view/XtKfRG +inline float caustic_pattern(float2 uv, float time) +{ + float3 k = float3(uv, time); + float3x3 m = float3x3(-2, -1, 2, 3, -2, 1, 1, 2, 2); + float3 a = mul(k, m) * 0.5; + float3 b = mul(a, m) * 0.4; + float3 c = mul(b, m) * 0.3; + return pow(min(min(length(0.5 - frac(a)), length(0.5 - frac(b))), length(0.5 - frac(c))), 7) * 25.; +} // Convert texture coordinates on a cubemap face to cubemap sampling coordinates: // uv : UV texture coordinates on cubemap face in range [0, 1] diff --git a/WickedEngine/shaders/lightingHF.hlsli b/WickedEngine/shaders/lightingHF.hlsli index df740be9d..9a88dbd5b 100644 --- a/WickedEngine/shaders/lightingHF.hlsli +++ b/WickedEngine/shaders/lightingHF.hlsli @@ -115,7 +115,6 @@ inline float3 shadow_cube(in ShaderEntity light, in float3 L, in float3 Lunnorma return shadow; } - inline void light_directional(in ShaderEntity light, in Surface surface, inout Lighting lighting, in float shadow_mask = 1) { float3 L = light.GetDirection(); @@ -187,6 +186,25 @@ inline void light_directional(in ShaderEntity light, in Surface surface, inout L lighting.direct.diffuse = mad(light_color, BRDF_GetDiffuse(surface, surface_to_light), lighting.direct.diffuse); lighting.direct.specular = mad(light_color, BRDF_GetSpecular(surface, surface_to_light), lighting.direct.specular); + +#ifndef WATER + const ShaderOcean ocean = GetWeather().ocean; + if (ocean.texture_displacementmap >= 0) + { + Texture2D displacementmap = bindless_textures[ocean.texture_displacementmap]; + float2 ocean_uv = surface.P.xz * ocean.patch_size_rcp; + float3 displacement = displacementmap.SampleLevel(sampler_linear_wrap, ocean_uv, 0).xzy; + float water_height = ocean.water_height + displacement.y; + if (surface.P.y < water_height) + { + float3 caustic = caustic_pattern(ocean_uv * 20, GetFrame().time); + caustic *= sqr(saturate((water_height - surface.P.y) * 0.5)); // fade out at shoreline + caustic *= light_color; + lighting.indirect.diffuse += caustic; + } + } +#endif // WATER + } } } diff --git a/WickedEngine/shaders/oceanSurfacePS.hlsl b/WickedEngine/shaders/oceanSurfacePS.hlsl index 3c919bbca..269652f91 100644 --- a/WickedEngine/shaders/oceanSurfacePS.hlsl +++ b/WickedEngine/shaders/oceanSurfacePS.hlsl @@ -2,6 +2,7 @@ #define DISABLE_ENVMAPS #define DISABLE_TRANSPARENT_SHADOWMAP #define TRANSPARENT +#define WATER #include "globals.hlsli" #include "oceanSurfaceHF.hlsli" #include "objectHF.hlsli" @@ -19,6 +20,10 @@ float4 main(PSIn input) : SV_TARGET V /= dist; float emissive = 0; + float ocean_level_at_camera_pos = xOceanWaterHeight; + ocean_level_at_camera_pos += texture_ocean_displacementmap.SampleLevel(sampler_linear_wrap, GetCamera().position.xz * xOceanPatchSizeRecip, 0).z; // texture contains xzy! + const bool camera_above_water = GetCamera().position.y > ocean_level_at_camera_pos; + const float gradient_fade = saturate(dist * 0.001); const float4 gradientNear = texture_gradientmap.Sample(sampler_aniso_wrap, input.uv); const float4 gradientFar = texture_gradientmap.Sample(sampler_aniso_wrap, input.uv * 0.125); @@ -31,7 +36,7 @@ float4 main(PSIn input) : SV_TARGET surface.pixel = input.pos.xy; float depth = input.pos.z; surface.albedo = color.rgb; - surface.f0 = 0.02; + surface.f0 = camera_above_water ? 0.02 : 0.1; surface.roughness = 0.1; surface.P = input.pos3D; surface.N = normalize(float3(gradient.x, xOceanTexelLength * 2, gradient.y)); @@ -46,6 +51,7 @@ float4 main(PSIn input) : SV_TARGET TiledLighting(surface, lighting); float2 ScreenCoord = surface.pixel * GetCamera().internal_resolution_rcp; + const float bump_strength = camera_above_water ? 0.04 : 0.1; [branch] if (GetCamera().texture_reflection_index >= 0) @@ -53,21 +59,19 @@ float4 main(PSIn input) : SV_TARGET //REFLECTION float4 reflectionPos = mul(GetCamera().reflection_view_projection, float4(input.pos3D, 1)); float2 reflectionUV = clipspace_to_uv(reflectionPos.xy / reflectionPos.w); - float4 reflectiveColor = bindless_textures[GetCamera().texture_reflection_index].SampleLevel(sampler_linear_mirror, reflectionUV + surface.N.xz * 0.04f, 0); + float4 reflectiveColor = bindless_textures[GetCamera().texture_reflection_index].SampleLevel(sampler_linear_mirror, reflectionUV + surface.N.xz * bump_strength, 0); lighting.indirect.specular = reflectiveColor.rgb * surface.F; } [branch] if (GetCamera().texture_refraction_index >= 0) { - // WATER REFRACTION + // WATER REFRACTION Texture2D texture_refraction = bindless_textures[GetCamera().texture_refraction_index]; - float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + surface.N.xz * 0.04f, 0) * GetCamera().z_far; + float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + surface.N.xz * bump_strength, 0) * GetCamera().z_far; float depth_difference = sampled_lineardepth - lineardepth; - surface.refraction.rgb = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + surface.N.xz * 0.04f * saturate(0.5 * depth_difference), 0).rgb; - float ocean_level_at_camera_pos = xOceanWaterHeight; - ocean_level_at_camera_pos += texture_ocean_displacementmap.SampleLevel(sampler_linear_wrap, GetCamera().position.xz * xOceanPatchSizeRecip, 0).z; // texture contains xzy! - if (GetCamera().position.y > ocean_level_at_camera_pos) + surface.refraction.rgb = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + surface.N.xz * bump_strength * saturate(0.5 * depth_difference), 0).rgb; + if (camera_above_water) { if (depth_difference < 0) { @@ -85,7 +89,7 @@ float4 main(PSIn input) : SV_TARGET } // Blend out at distance: - color.a = pow(saturate(1 - saturate(dist / GetCamera().z_far)), 2); + color.a = saturate(1 - saturate(dist / GetCamera().z_far - 0.8) * 5.0); // fade will be on edge and inwards 20% color.a = lerp(0, color.a, saturate(pow(lineardepth, 2))); // fade when very close to camera ApplyLighting(surface, lighting, color); diff --git a/WickedEngine/shaders/oceanSurfaceVS.hlsl b/WickedEngine/shaders/oceanSurfaceVS.hlsl index f3c3d51c4..6afa3e6db 100644 --- a/WickedEngine/shaders/oceanSurfaceVS.hlsl +++ b/WickedEngine/shaders/oceanSurfaceVS.hlsl @@ -30,6 +30,8 @@ PSIn main(uint vertexID : SV_VertexID) { // Displace surface: float3 displacement = texture_displacementmap.SampleLevel(sampler_linear_wrap, uv, 0).xzy; + float dist = length(worldPos - GetCamera().position); + displacement *= saturate(1 - saturate(dist / GetCamera().z_far - 0.8) * 5.0); // fade will be on edge and inwards 20% worldPos += displacement; } diff --git a/WickedEngine/shaders/shadowPS_water.hlsl b/WickedEngine/shaders/shadowPS_water.hlsl index e50288bbd..400b222a1 100644 --- a/WickedEngine/shaders/shadowPS_water.hlsl +++ b/WickedEngine/shaders/shadowPS_water.hlsl @@ -25,28 +25,7 @@ float4 main(PixelInput input) : SV_TARGET color.rgb = 1; // disable water shadow because it has already fog - [branch] - if (GetMaterial().uvset_normalMap >= 0) - { - float3 bumpColor; - - float2 bumpColor0 = 0; - float2 bumpColor1 = 0; - float2 bumpColor2 = 0; - const float2 UV_normalMap = GetMaterial().uvset_normalMap == 0 ? input.uvsets.xy : input.uvsets.zw; - bumpColor0 = 2.0f * texture_normalmap.Sample(sampler_objectshader, UV_normalMap - GetMaterial().texMulAdd.ww).rg - 1.0f; - bumpColor1 = 2.0f * texture_normalmap.Sample(sampler_objectshader, UV_normalMap + GetMaterial().texMulAdd.zw).rg - 1.0f; - bumpColor = float3(bumpColor0 + bumpColor1 + bumpColor2, 1) * GetMaterial().refraction; - bumpColor.rg *= GetMaterial().normalMapStrength; - bumpColor = normalize(max(bumpColor, float3(0, 0, 0.0001f))); - - float caustic = abs(dot(bumpColor, float3(0, 1, 0))); - caustic = saturate(caustic); - caustic = pow(caustic, 2); - caustic *= 20; - - color.rgb += caustic; - } + color.rgb += caustic_pattern(input.uvsets.xy * 20, GetFrame().time); color.a = input.pos.z; // secondary depth diff --git a/WickedEngine/shaders/underwaterCS.hlsl b/WickedEngine/shaders/underwaterCS.hlsl index f420bd3ed..86985d1fb 100644 --- a/WickedEngine/shaders/underwaterCS.hlsl +++ b/WickedEngine/shaders/underwaterCS.hlsl @@ -1,6 +1,7 @@ #include "globals.hlsli" #include "ShaderInterop_Postprocess.h" #include "oceanSurfaceHF.hlsli" +#include "lightingHF.hlsli" PUSHCONSTANT(postprocess, PostProcess); @@ -52,7 +53,7 @@ void main(uint3 DTid : SV_DispatchThreadID) const float ocean_dist = length(ocean_surface_pos - o); const float min_dist = min(lineardepth, ocean_dist); - float3 modified_color = lerp(color.rgb, ocean.water_color.rgb, saturate(0.5 + min_dist * 0.025)); + float3 modified_color = lerp(color.rgb, ocean.water_color.rgb, saturate(0.5 + min_dist * 0.025 * ocean.water_color.a)); color.rgb = lerp(color.rgb, modified_color, pow(saturate(ocean_pos.y - world_pos.y), 0.25)); } output[DTid.xy] = color; diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 9c78de8cc..843c88ef3 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -1862,6 +1862,7 @@ namespace wi::scene shaderscene.weather.sun_color = weather.sunColor; shaderscene.weather.sun_direction = weather.sunDirection; shaderscene.weather.sun_energy = weather.sunEnergy; + shaderscene.weather.most_important_light_index = weather.most_important_light_index; shaderscene.weather.ambient = weather.ambient; shaderscene.weather.cloudiness = weather.cloudiness; shaderscene.weather.cloud_scale = weather.cloudScale; @@ -1882,9 +1883,9 @@ namespace wi::scene shaderscene.weather.volumetric_clouds = weather.volumetricCloudParameters; shaderscene.weather.ocean.water_color = weather.oceanParameters.waterColor; shaderscene.weather.ocean.water_height = weather.oceanParameters.waterHeight; - shaderscene.weather.ocean.patch_size = weather.oceanParameters.patch_length; shaderscene.weather.ocean.patch_size_rcp = 1.0f / weather.oceanParameters.patch_length; shaderscene.weather.ocean.texture_displacementmap = device->GetDescriptorIndex(ocean.getDisplacementMap(), SubresourceType::SRV); + shaderscene.weather.ocean.texture_gradientmap = device->GetDescriptorIndex(ocean.getGradientMap(), SubresourceType::SRV); shaderscene.ddgi.color_texture = device->GetDescriptorIndex(&ddgiColorTexture[0], SubresourceType::SRV); shaderscene.ddgi.depth_texture = device->GetDescriptorIndex(&ddgiDepthTexture[0], SubresourceType::SRV); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 82153ae42..16249b9bc 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 60; // minor bug fixes, alterations, refactors, updates - const int revision = 47; + const int revision = 48; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);