From eaf03b600525f1dd1c451a3199303a893f88b855 Mon Sep 17 00:00:00 2001 From: Stuart Buchanan <stuart_d_buchanan@yahoo.co.uk> Date: Sun, 5 Dec 2021 14:15:27 +0000 Subject: [PATCH] Add object shadows to water commit 918aa4402143638133153dff722ef3a6b4feead7 Author: vs <vs2009@mail.com> Date: Sat Nov 20 23:38:52 2021 +1000 ALS water effect & shaders: Add object shadows for water in a similar fashion to terrain. Add commented out code of what should be the shader part of clustered lighting for the compositor. getClusteredLightsContribution() normally multiplies the texel by light contributions. It is fed input such that the light contribution term is similar to secondary lights in the water lighting equation, and both are added together. --- Effects/water.eff | 49 +++++++++++++++++++++++++++++++++++++ Shaders/water-ALS-base.frag | 18 ++++++++++++++ Shaders/water-ALS-high.frag | 25 ++++++++++++------- Shaders/water-ALS.vert | 8 ++++-- 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/Effects/water.eff b/Effects/water.eff index b6648efe1..66bc48143 100644 --- a/Effects/water.eff +++ b/Effects/water.eff @@ -411,12 +411,15 @@ <program> <vertex-shader>Shaders/water-ALS.vert</vertex-shader> + <vertex-shader>Shaders/shadows-include.vert</vertex-shader> <fragment-shader>Shaders/water-ALS-high.frag</fragment-shader> <fragment-shader>Shaders/noise.frag</fragment-shader> <fragment-shader>Shaders/cloud-shadowfunc.frag</fragment-shader> <fragment-shader>Shaders/hazes.frag</fragment-shader> <fragment-shader>Shaders/secondary_lights.frag</fragment-shader> <fragment-shader>Shaders/filters-ALS.frag</fragment-shader> + <fragment-shader>Shaders/shadows-include.frag</fragment-shader> + <fragment-shader>Shaders/clustered-include.frag</fragment-shader> </program> <!--<uniform> <name>water_reflection</name> @@ -458,6 +461,27 @@ <type>sampler-2d</type> <value type="int">8</value> </uniform> + <!-- BEGIN shadows include --> + <uniform> + <name>shadow_tex</name> + <type>sampler-2d</type> + <value type="int">10</value> + </uniform> + <uniform> + <name>shadows_enabled</name> + <type>bool</type> + <value> + <use>shadows_enabled</use> + </value> + </uniform> + <uniform> + <name>sun_atlas_size</name> + <type>int</type> + <value> + <use>sun_atlas_size</use> + </value> + </uniform> + <!-- END shadows include --> <uniform> <name>use_specified_water_shallowness</name> <type>int</type> @@ -1183,10 +1207,14 @@ <program> <vertex-shader>Shaders/water-ALS.vert</vertex-shader> + <vertex-shader>Shaders/shadows-include.vert</vertex-shader> <fragment-shader>Shaders/water-ALS-base.frag</fragment-shader> <fragment-shader>Shaders/hazes.frag</fragment-shader> + <fragment-shader>Shaders/secondary_lights.frag</fragment-shader> <fragment-shader>Shaders/noise.frag</fragment-shader> <fragment-shader>Shaders/filters-ALS.frag</fragment-shader> + <fragment-shader>Shaders/shadows-include.frag</fragment-shader> + <fragment-shader>Shaders/clustered-include.frag</fragment-shader> </program> <!--<uniform> <name>water_reflection</name> @@ -1213,6 +1241,27 @@ <type>sampler-2d</type> <value type="int">6</value> </uniform> + <!-- BEGIN shadows include --> + <uniform> + <name>shadow_tex</name> + <type>sampler-2d</type> + <value type="int">10</value> + </uniform> + <uniform> + <name>shadows_enabled</name> + <type>bool</type> + <value> + <use>shadows_enabled</use> + </value> + </uniform> + <uniform> + <name>sun_atlas_size</name> + <type>int</type> + <value> + <use>sun_atlas_size</use> + </value> + </uniform> + <!-- END shadows include --> <!-- normalmap is .dds--> <uniform> <name>normalmap_dds</name> diff --git a/Shaders/water-ALS-base.frag b/Shaders/water-ALS-base.frag index 1a5d203c1..43a0c0da0 100644 --- a/Shaders/water-ALS-base.frag +++ b/Shaders/water-ALS-base.frag @@ -24,6 +24,7 @@ varying vec3 viewerdir; varying vec3 lightdir; //varying vec3 specular_light; varying vec3 relPos; +varying vec4 ecPosition; varying float earthShade; varying float yprime_alt; @@ -61,9 +62,13 @@ const float terminator_width = 200000.0; const float EarthRadius = 5800000.0; float fog_func (in float targ, in float alt); +float light_distance_fading(in float dist); vec3 get_hazeColor(in float light_arg); vec3 filter_combined (in vec3 color) ; +float getShadowing(); +vec3 getClusteredLightsContribution(vec3 p, vec3 n, vec3 texel); + /////// functions ///////// void rotationmatrix(in float angle, out mat4 rotmat) @@ -385,10 +390,23 @@ void main(void) vec4 finalColor; + // compute object shadow effect + + float shadowValue = getShadowing(); + specular = specular * shadowValue; + refl = refl * (0.7 + 0.3 *shadowValue); finalColor = refl + specular * smoothstep(0.3, 0.6, ground_scattering); + + // For the clustered lighting function we use the simple up direction (Normal) to get an + // approximate lighting contribution, as the procedural normal map is done afterwards. + //finalColor += vec4(getClusteredLightsContribution(ecPosition.xyz, Normal, vec3(1.0)), 0.0) * light_distance_fading(dist) * 2.0 * pow(max(0.0,dot(E,N)), water_shininess); + + + + //add foam vec4 foam_texel = texture2D(sea_foam, vec2(waterTex2 * tscale) * 25.0); diff --git a/Shaders/water-ALS-high.frag b/Shaders/water-ALS-high.frag index adf37d64b..d7b3f0aa1 100644 --- a/Shaders/water-ALS-high.frag +++ b/Shaders/water-ALS-high.frag @@ -28,6 +28,8 @@ varying vec3 lightdir; varying vec3 relPos; varying vec3 rawPos; varying vec2 TopoUV; +varying vec4 ecPosition; + uniform vec3 floor_color; varying float earthShade; @@ -102,6 +104,8 @@ vec3 searchlight(); vec3 landing_light(in float offset, in float offsetv); vec3 filter_combined (in vec3 color) ; +float getShadowing(); +vec3 getClusteredLightsContribution(vec3 p, vec3 n, vec3 texel); ////////////////////// @@ -473,15 +477,12 @@ void main(void) vec4 finalColor; - // compute cloud shadow effect + // compute cloud and object shadow effects - float shadowValue; - if (cloud_shadow_flag == 1) - { - shadowValue = shadow_func(relPos.x, relPos.y, 0.3 * noise_250m + 0.5 * noise_500m+0.2 * noise_1500m, dist); - specular = specular * shadowValue; - refl = refl * (0.7 + 0.3 *shadowValue); - } + float shadowValue = getShadowing(); + if (cloud_shadow_flag == 1) { shadowValue *= shadow_func(relPos.x, relPos.y, 0.3 * noise_250m + 0.5 * noise_500m+0.2 * noise_1500m, dist); } + specular = specular * shadowValue; + refl = refl * (0.7 + 0.3 *shadowValue); // compute secondary light effect @@ -506,7 +507,13 @@ void main(void) - finalColor = refl + specular * smoothstep(0.3, 0.6, ground_scattering) + vec4 (secondary_light, 0.0) * light_distance_fading(dist) * 2.0 * pow(max(0.0,dot(E,N)), water_shininess); + finalColor = refl + specular * smoothstep(0.3, 0.6, ground_scattering); + + // For the clustered lighting function we use the simple up direction (Normal) to get an + // approximate lighting contribution, as the procedural normal map is done afterwards. + //vec3 light_contribution = secondary_light + getClusteredLightsContribution(ecPosition.xyz, Normal, vec3(1.0)); + vec3 light_contribution = secondary_light; + finalColor += vec4(light_contribution, 0.0) * light_distance_fading(dist) * 2.0 * pow(max(0.0,dot(E,N)), water_shininess); finalColor = clamp(finalColor, 0.0,1.0); diff --git a/Shaders/water-ALS.vert b/Shaders/water-ALS.vert index 750bdec7d..a81dd65e9 100644 --- a/Shaders/water-ALS.vert +++ b/Shaders/water-ALS.vert @@ -13,6 +13,7 @@ varying vec4 waterTex4; varying vec3 relPos; varying vec3 rawPos; varying vec2 TopoUV; +varying vec4 ecPosition; varying vec3 viewerdir; varying vec3 lightdir; @@ -47,10 +48,13 @@ const float lonAdjust = 0.9999537058469516; //actual extents: +-180.008333333333 vec3 specular_light; +void setupShadows(vec4 eyeSpacePos); + // This is the value used in the skydome scattering shader - use the same here for consistency? const float EarthRadius = 5800000.0; const float terminator_width = 200000.0; + float light_func (in float x, in float a, in float b, in float c, in float d, in float e) { //x = x - 0.5; @@ -87,7 +91,7 @@ void main(void) vec3 shadedFogColor = vec3(0.55, 0.67, 0.88); rawPos = (osg_ViewMatrixInverse *gl_ModelViewMatrix * gl_Vertex).xyz; - vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; + ecPosition = gl_ModelViewMatrix * gl_Vertex; viewerdir = vec3(gl_ModelViewMatrixInverse[3]) - vec3(gl_Vertex); lightdir = normalize(vec3(gl_ModelViewMatrixInverse * gl_LightSource[0].position)); @@ -292,5 +296,5 @@ else // the faster, full-day version without lightfields gl_FrontColor.rgb = specular_light; gl_BackColor.rgb = gl_FrontColor.rgb; - + setupShadows(ecPosition); }