From f004c4e6f9dfd0ffd31dac897d7fc367aa1d440b Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Fri, 27 Dec 2019 13:09:50 +1100 Subject: [PATCH 1/7] Add vertex lights support. Experimental --- crest/Assets/Crest/Crest/Shaders/Ocean.shader | 40 ++++++++++++++++--- .../Crest/Crest/Shaders/OceanEmission.hlsl | 9 ++++- .../Assets/Crest/Crest/Shaders/OceanFoam.hlsl | 20 ++++++++-- .../Crest/Shaders/OceanLightingHelpers.hlsl | 28 +++++++++++++ .../Shaders/OceanLightingHelpers.hlsl.meta | 9 +++++ .../Crest/Crest/Shaders/OceanReflection.hlsl | 23 ++++++++--- .../Underwater/UnderwaterCurtain.shader | 26 +++++++++++- 7 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl create mode 100644 crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl.meta diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index 95d94383d..a54409030 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -164,6 +164,15 @@ Shader "Crest/Ocean" // enabled on the OceanRenderer to generate flow data. [Toggle] _Flow("Enable", Float) = 0 + [Header(Lights)] + // How much the light will fill its sphere of influence + _LightsSubSurfaceBase("Sub Surface Base Mul", Range(0.0, 4.0)) = 1.0 + // Strength of specular lighting response + _LightsSpecular("Specular", Range(0.0, 1000.0)) = 31.0 + // Light strength on foam + _LightsScaleWaveFoam("Foam Lights Scale", Range(0.0, 1000.0)) = 5.0 + _LightsFresnelPower("Fresnel Power", Range(1.0, 20.0)) = 10.0 + [Header(Debug Options)] // Build shader with debug info which allows stepping through the code in a GPU debugger. I typically use RenderDoc or // PIX for Windows (requires DX12 API to be selected). @@ -197,6 +206,7 @@ Shader "Crest/Ocean" // for VFACE #pragma target 3.0 #pragma multi_compile_fog + #pragma multi_compile _ VERTEXLIGHT_ON #pragma shader_feature _APPLYNORMALMAPPING_ON #pragma shader_feature _COMPUTEDIRECTIONALLIGHT_ON @@ -245,11 +255,15 @@ Shader "Crest/Ocean" half3 debugtint : TEXCOORD8; #endif half4 grabPos : TEXCOORD9; + #if defined(VERTEXLIGHT_ON) + half4 uvLightsAtten : TEXCOORD10; + #endif // VERTEXLIGHT_ON UNITY_FOG_COORDS(3) }; #include "OceanHelpers.hlsl" + #include "OceanLightingHelpers.hlsl" float _CrestTime; @@ -365,6 +379,12 @@ Shader "Crest/Ocean" // to get the right results, every time. o.grabPos = ComputeGrabScreenPos(o.positionCS); o.foam_screenPosXYW.yzw = ComputeScreenPos(o.positionCS).xyw; + + // Calculate vertex light attenuation here to save on performance + #if defined(VERTEXLIGHT_ON) + CalculateVertexLightsAttenuation(o.uvLightsAtten, o.worldPos); + #endif // VERTEXLIGHT_ON + return o; } @@ -377,6 +397,9 @@ Shader "Crest/Ocean" #include "OceanNormalMapping.hlsl" uniform sampler2D _CameraDepthTexture; + #if defined(VERTEXLIGHT_ON) + uniform sampler2D _LightTextureB0; + #endif // VERTEXLIGHT_ON // Hack - due to SV_IsFrontFace occasionally coming through as true for backfaces, // add a param here that forces ocean to be in undrwater state. I think the root @@ -419,6 +442,13 @@ Shader "Crest/Ocean" float sceneZ = LinearEyeDepth(sceneZ01); float3 lightDir = WorldSpaceLightDir(input.worldPos); + half3 lightsCol = 0; + + // Calculate + #if defined(VERTEXLIGHT_ON) + lightsCol = CalculateVertexLightsColor(input.uvLightsAtten, input.worldPos, _LightTextureB0); + #endif // VERTEXLIGHT_ON + // Soft shadow, hard shadow fixed2 shadow = (fixed2)1.0 #if _SHADOWS_ON @@ -454,14 +484,14 @@ Shader "Crest/Ocean" #if _FOAM_ON half4 whiteFoamCol; #if !_FLOW_ON - ComputeFoam(input.foam_screenPosXYW.x, input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.worldPos.xz, n_pixel, pixelZ, sceneZ, view, lightDir, shadow.y, lodAlpha, bubbleCol, whiteFoamCol); + ComputeFoam(input.foam_screenPosXYW.x, input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.worldPos.xz, n_pixel, pixelZ, sceneZ, view, lightDir, shadow.y, lodAlpha, bubbleCol, whiteFoamCol, lightsCol); #else - ComputeFoamWithFlow(input.flow_shadow.xy, input.foam_screenPosXYW.x, input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.worldPos.xz, n_pixel, pixelZ, sceneZ, view, lightDir, shadow.y, lodAlpha, bubbleCol, whiteFoamCol); + ComputeFoamWithFlow(input.flow_shadow.xy, input.foam_screenPosXYW.x, input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.worldPos.xz, n_pixel, pixelZ, sceneZ, view, lightDir, shadow.y, lodAlpha, bubbleCol, whiteFoamCol, lightsCol); #endif // _FLOW_ON #endif // _FOAM_ON // Compute color of ocean - in-scattered light + refracted scene - half3 scatterCol = ScatterColour(input.lodAlpha_worldXZUndisplaced_oceanDepth.w, _WorldSpaceCameraPos, lightDir, view, shadow.x, underwater, true, sss); + half3 scatterCol = ScatterColour(input.lodAlpha_worldXZUndisplaced_oceanDepth.w, _WorldSpaceCameraPos, lightDir, view, shadow.x, underwater, true, sss, lightsCol); half3 col = OceanEmission(view, n_pixel, lightDir, input.grabPos, pixelZ, uvDepth, sceneZ, sceneZ01, bubbleCol, _Normals, _CameraDepthTexture, underwater, scatterCol); // Light that reflects off water surface @@ -474,7 +504,7 @@ Shader "Crest/Ocean" // disable transparency, so this will always be 1.0. float reflAlpha = 1.0; #endif - + #if _UNDERWATER_ON if (underwater) { @@ -483,7 +513,7 @@ Shader "Crest/Ocean" else #endif { - ApplyReflectionSky(view, n_pixel, lightDir, shadow.y, input.foam_screenPosXYW.yzzw, pixelZ, reflAlpha, col); + ApplyReflectionSky(view, n_pixel, lightDir, shadow.y, input.foam_screenPosXYW.yzzw, pixelZ, reflAlpha, col, lightsCol); } // Override final result with white foam - bubbles on surface diff --git a/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl index 72aaca747..abb1bcdf8 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl @@ -20,6 +20,9 @@ uniform half3 _SubSurfaceColour; uniform half _SubSurfaceBase; uniform half _SubSurfaceSun; uniform half _SubSurfaceSunFallOff; +#if defined(VERTEXLIGHT_ON) +uniform half _LightsSubSurfaceBase; +#endif // VERTEXLIGHT_ON #endif // _SUBSURFACESCATTERING_ON #if _SUBSURFACESHALLOWCOLOUR_ON @@ -49,7 +52,7 @@ uniform half3 _DiffuseShadow; half3 ScatterColour( in const half i_surfaceOceanDepth, in const float3 i_cameraPos, in const half3 i_lightDir, in const half3 i_view, in const fixed i_shadow, - in const bool i_underwater, in const bool i_outscatterLight, half sss) + in const bool i_underwater, in const bool i_outscatterLight, half sss, half3 lightsCol) { half depth; half shadow = 1.0; @@ -110,6 +113,10 @@ half3 ScatterColour( // light // use the constant term (0th order) of SH stuff - this is the average. it seems to give the right kind of colour col *= half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); + // Apply vertex lights if available +#if defined(VERTEXLIGHT_ON) + col += lightsCol * _LightsSubSurfaceBase; +#endif // VERTEXLIGHT_ON // Approximate subsurface scattering - add light when surface faces viewer. Use geometry normal - don't need high freqs. half towardsSun = pow(max(0., dot(i_lightDir, -i_view)), _SubSurfaceSunFallOff); diff --git a/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl index 09c11d315..f4c7cfb1b 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl @@ -17,6 +17,9 @@ uniform half _WaveFoamNormalStrength; uniform half _WaveFoamSpecularFallOff; uniform half _WaveFoamSpecularBoost; uniform half _WaveFoamLightScale; +#if defined(VERTEXLIGHT_ON) +uniform half _LightsScaleWaveFoam; +#endif // VERTEXLIGHT_ON half3 AmbientLight() { @@ -48,7 +51,7 @@ half BubbleFoamTexture(float2 i_worldXZ, float2 i_worldXZUndisplaced, half3 i_n, return ft; } -void ComputeFoam(half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, half3 i_n, float i_pixelZ, float i_sceneZ, half3 i_view, float3 i_lightDir, half i_shadow, half lodVal, out half3 o_bubbleCol, out half4 o_whiteFoamCol) +void ComputeFoam(half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, half3 i_n, float i_pixelZ, float i_sceneZ, half3 i_view, float3 i_lightDir, half i_shadow, half lodVal, out half3 o_bubbleCol, out half4 o_whiteFoamCol, half3 lightsCol) { half foamAmount = i_foam; @@ -58,6 +61,9 @@ void ComputeFoam(half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, hal // Additive underwater foam - use same foam texture but add mip bias to blur for free half bubbleFoamTexValue = BubbleFoamTexture(i_worldXZ, i_worldXZUndisplaced, i_n, i_view, lodVal); o_bubbleCol = (half3)bubbleFoamTexValue * _FoamBubbleColor.rgb * saturate(i_foam * _WaveFoamBubblesCoverage) * AmbientLight(); +#if defined(VERTEXLIGHT_ON) + o_bubbleCol += lightsCol; +#endif // VERTEXLIGHT_ON // White foam on top, with black-point fading half whiteFoam = WhiteFoamTexture(foamAmount, i_worldXZUndisplaced, lodVal); @@ -74,16 +80,22 @@ void ComputeFoam(half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, hal // do simple NdL and phong lighting half foamNdL = max(0., dot(fN, i_lightDir)); o_whiteFoamCol.rgb = _FoamWhiteColor.rgb * (AmbientLight() + _WaveFoamLightScale * _LightColor0 * foamNdL * i_shadow); +#if defined(VERTEXLIGHT_ON) + o_whiteFoamCol.rgb += lightsCol * _WaveFoamLightScale * _LightsScaleWaveFoam; +#endif // VERTEXLIGHT_ON half3 refl = reflect(-i_view, fN); o_whiteFoamCol.rgb += pow(max(0., dot(refl, i_lightDir)), _WaveFoamSpecularFallOff) * _WaveFoamSpecularBoost * _LightColor0 * i_shadow; #else // _FOAM3DLIGHTING_ON o_whiteFoamCol.rgb = _FoamWhiteColor.rgb * (AmbientLight() + _WaveFoamLightScale * _LightColor0 * i_shadow); +#if defined(VERTEXLIGHT_ON) + o_whiteFoamCol.rgb += lightsCol * _WaveFoamLightScale * _LightsScaleWaveFoam; +#endif // VERTEXLIGHT_ON #endif // _FOAM3DLIGHTING_ON o_whiteFoamCol.a = _FoamWhiteColor.a * whiteFoam; } -void ComputeFoamWithFlow(half2 flow, half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, half3 i_n, float i_pixelZ, float i_sceneZ, half3 i_view, float3 i_lightDir, half i_shadow, half lodVal, out half3 o_bubbleCol, out half4 o_whiteFoamCol) +void ComputeFoamWithFlow(half2 flow, half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, half3 i_n, float i_pixelZ, float i_sceneZ, half3 i_view, float3 i_lightDir, half i_shadow, half lodVal, out half3 o_bubbleCol, out half4 o_whiteFoamCol, half3 lightsCol) { const float half_period = 1; const float period = half_period * 2; @@ -101,8 +113,8 @@ void ComputeFoamWithFlow(half2 flow, half i_foam, float2 i_worldXZUndisplaced, f half3 o_bubbleCol2 = half3(0, 0, 0); half4 o_whiteFoamCol2 = half4(0, 0, 0, 0); - ComputeFoam(i_foam, i_worldXZUndisplaced - (flow * sample1_offset), i_worldXZ, i_n, i_pixelZ, i_sceneZ, i_view, i_lightDir, i_shadow, lodVal, o_bubbleCol1, o_whiteFoamCol1); - ComputeFoam(i_foam, i_worldXZUndisplaced - (flow * sample2_offset), i_worldXZ, i_n, i_pixelZ, i_sceneZ, i_view, i_lightDir, i_shadow, lodVal, o_bubbleCol2, o_whiteFoamCol2); + ComputeFoam(i_foam, i_worldXZUndisplaced - (flow * sample1_offset), i_worldXZ, i_n, i_pixelZ, i_sceneZ, i_view, i_lightDir, i_shadow, lodVal, o_bubbleCol1, o_whiteFoamCol1, lightsCol); + ComputeFoam(i_foam, i_worldXZUndisplaced - (flow * sample2_offset), i_worldXZ, i_n, i_pixelZ, i_sceneZ, i_view, i_lightDir, i_shadow, lodVal, o_bubbleCol2, o_whiteFoamCol2, lightsCol); o_bubbleCol = (sample1_weight * o_bubbleCol1) + (sample2_weight * o_bubbleCol2); o_whiteFoamCol = (sample1_weight * o_whiteFoamCol1) + (sample2_weight * o_whiteFoamCol2); } diff --git a/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl new file mode 100644 index 000000000..e2fb84288 --- /dev/null +++ b/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl @@ -0,0 +1,28 @@ +// Crest Ocean System + +// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) + +// Improved attenuation for vertex lights. Call this routine in the vertex shader to save on performance. +// https://forum.unity.com/threads/point-light-in-v-f-shader.499717/#post-3250481 +void CalculateVertexLightsAttenuation(out half4 uv, in const float3 positionWS) +{ + for (int index = 0; index < 4; index++) + { + float3 lightPosition = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]); + float range = (0.005 * sqrt(1000000 - unity_4LightAtten0[index])) / sqrt(unity_4LightAtten0[index]); + uv[index] = distance(lightPosition, positionWS.xyz) / range; + } +} + +// Returns vertex light colour with custom attenuation. Call in fragment shader. +half3 CalculateVertexLightsColor(in const half4 uv, in const float3 positionWS, in const sampler2D lightsTexture) +{ + half3 lightsColor = 0; + for (int index = 0; index < 4; index++) + { + float3 lightPosition = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]); + float attenuation = tex2D(lightsTexture, (uv[index] * uv[index]).xx).UNITY_ATTEN_CHANNEL; + lightsColor.rgb += unity_LightColor[index].rgb * (1 / distance(lightPosition, positionWS.xyz)) * attenuation; + } + return lightsColor; +} diff --git a/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl.meta b/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl.meta new file mode 100644 index 000000000..c7ca826b4 --- /dev/null +++ b/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0d5c98ca976f74c60898d29980bfe6cf +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/crest/Assets/Crest/Crest/Shaders/OceanReflection.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanReflection.hlsl index 21bc8215f..eb474ce67 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanReflection.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanReflection.hlsl @@ -43,6 +43,10 @@ uniform half _FresnelPower; uniform float _RefractiveIndexOfAir; uniform float _RefractiveIndexOfWater; +#if defined(VERTEXLIGHT_ON) +uniform half _LightsSpecular; +uniform half _LightsFresnelPower; +#endif // VERTEXLIGHT_ON #if _COMPUTEDIRECTIONALLIGHT_ON uniform half _DirectionalLightFallOff; @@ -51,17 +55,17 @@ uniform half _DirectionalLightFallOffFar; uniform half _DirectionalLightBoost; #endif -float CalculateFresnelReflectionCoefficient(float cosTheta) +float CalculateFresnelReflectionCoefficient(float cosTheta, half fresnelPower) { // Fresnel calculated using Schlick's approximation // See: http://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf // reflectance at facing angle float R_0 = (_RefractiveIndexOfAir - _RefractiveIndexOfWater) / (_RefractiveIndexOfAir + _RefractiveIndexOfWater); R_0 *= R_0; - const float R_theta = R_0 + (1.0 - R_0) * pow(max(0.,1.0 - cosTheta), _FresnelPower); + const float R_theta = R_0 + (1.0 - R_0) * pow(max(0.,1.0 - cosTheta), fresnelPower); return R_theta; } -void ApplyReflectionSky(in const half3 i_view, in const half3 i_n_pixel, in const half3 i_lightDir, in const half i_shadow, in const half4 i_screenPos, in const float i_pixelZ, in const half i_weight, inout half3 io_col) +void ApplyReflectionSky(in const half3 i_view, in const half3 i_n_pixel, in const half3 i_lightDir, in const half i_shadow, in const half4 i_screenPos, in const float i_pixelZ, in const half i_weight, inout half3 io_col, float3 lightsCol) { // Reflection half3 refl = reflect(-i_view, i_n_pixel); @@ -108,8 +112,15 @@ void ApplyReflectionSky(in const half3 i_view, in const half3 i_n_pixel, in cons #endif // Fresnel - float R_theta = CalculateFresnelReflectionCoefficient(max(dot(i_n_pixel, i_view), 0.0)); + float R_theta = CalculateFresnelReflectionCoefficient(max(dot(i_n_pixel, i_view), 0.0), _FresnelPower); io_col = lerp(io_col, skyColour, R_theta * _Specular * i_weight); + + // Placing this here for now. Could be in its own routine + // Use lights specific fresnel for nicer effects +#if VERTEXLIGHT_ON + float R_theta2 = CalculateFresnelReflectionCoefficient(max(dot(i_n_pixel, i_view), 0.0), _LightsFresnelPower); + io_col = lerp(io_col, io_col + lightsCol, R_theta2 * _Specular * _LightsSpecular * i_weight); +#endif // VERTEXLIGHT_ON } #if _UNDERWATER_ON @@ -125,7 +136,7 @@ void ApplyReflectionUnderwater(in const half3 i_view, in const half3 i_n_pixel, // have to calculate the incident angle of incoming light to water // surface based on how it would be refracted so as to hit the camera const float cosIncomingAngle = cos(asin(clamp( (_RefractiveIndexOfWater * sin(acos(cosOutgoingAngle))) / _RefractiveIndexOfAir, -1.0, 1.0) )); - const float reflectionCoefficient = CalculateFresnelReflectionCoefficient(cosIncomingAngle) * i_weight; + const float reflectionCoefficient = CalculateFresnelReflectionCoefficient(cosIncomingAngle, _FresnelPower) * i_weight; io_col *= (1.0 - reflectionCoefficient); io_col = max(io_col, 0.0); } @@ -134,7 +145,7 @@ void ApplyReflectionUnderwater(in const half3 i_view, in const half3 i_n_pixel, { // angle of incident is angle of reflection const float cosIncomingAngle = cosOutgoingAngle; - const float reflectionCoefficient = CalculateFresnelReflectionCoefficient(cosIncomingAngle) * i_weight; + const float reflectionCoefficient = CalculateFresnelReflectionCoefficient(cosIncomingAngle, _FresnelPower) * i_weight; io_col += (underwaterColor * reflectionCoefficient); } } diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index dbf06fed5..3b0091fd4 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -37,6 +37,8 @@ Shader "Crest/Underwater Curtain" #pragma vertex Vert #pragma fragment Frag + #pragma multi_compile _ VERTEXLIGHT_ON + #pragma shader_feature _SUBSURFACESCATTERING_ON #pragma shader_feature _SUBSURFACESHALLOWCOLOUR_ON #pragma shader_feature _TRANSPARENCY_ON @@ -60,12 +62,17 @@ Shader "Crest/Underwater Curtain" float3 _InstanceData; #include "../OceanEmission.hlsl" + #include "../OceanLightingHelpers.hlsl" #define MAX_OFFSET 5.0 sampler2D _CameraDepthTexture; sampler2D _Normals; +#if defined(VERTEXLIGHT_ON) + uniform sampler2D _LightTextureB0; +#endif // VERTEXLIGHT_ON + struct Attributes { float3 positionOS : POSITION; @@ -79,6 +86,9 @@ Shader "Crest/Underwater Curtain" half4 foam_screenPos : TEXCOORD1; half4 grabPos : TEXCOORD2; float3 positionWS : TEXCOORD3; +#if defined(VERTEXLIGHT_ON) + half4 uvLightsAtten : TEXCOORD10; +#endif // VERTEXLIGHT_ON }; Varyings Vert(Attributes input) @@ -165,6 +175,11 @@ Shader "Crest/Underwater Curtain" o.uv = input.uv; + // Calculate vertex light attenuation here to save on performance +#if defined(VERTEXLIGHT_ON) + CalculateVertexLightsAttenuation(o.uvLightsAtten, o.positionWS); +#endif // VERTEXLIGHT_ON + return o; } @@ -191,7 +206,16 @@ Shader "Crest/Underwater Curtain" const float depth = 0.0; const half shadow = 1.0; - const half3 scatterCol = ScatterColour(depth, _WorldSpaceCameraPos, lightDir, view, shadow, true, true, sss); + half3 lightsCol = 0; + + // Calculate vertex lights colour +#if defined(VERTEXLIGHT_ON) + lightsCol = CalculateVertexLightsColor(input.uvLightsAtten, input.positionWS, _LightTextureB0); + // Decrease intensity so it isn't overwhelming + lightsCol *= 0.5; +#endif // VERTEXLIGHT_ON + + const half3 scatterCol = ScatterColour(depth, _WorldSpaceCameraPos, lightDir, view, shadow, true, true, sss, lightsCol); half3 sceneColour = tex2D(_BackgroundTexture, input.grabPos.xy / input.grabPos.w).rgb; From e8e19b63b7b960c3c881c9f78a15c4621799121d Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Sat, 28 Dec 2019 16:19:02 +1100 Subject: [PATCH 2/7] Add comment about Shade4PointLights --- crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl | 1 + 1 file changed, 1 insertion(+) diff --git a/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl index e2fb84288..e16062ee9 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanLightingHelpers.hlsl @@ -3,6 +3,7 @@ // This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) // Improved attenuation for vertex lights. Call this routine in the vertex shader to save on performance. +// Shade4PointLights produces tiling even though it applies attenuation. // https://forum.unity.com/threads/point-light-in-v-f-shader.499717/#post-3250481 void CalculateVertexLightsAttenuation(out half4 uv, in const float3 positionWS) { From 3d94df07918fff47f8e44519e55a9e0fec5ab101 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Sat, 28 Dec 2019 17:42:00 +1100 Subject: [PATCH 3/7] Multiply bubbles by lights Multiplying gave bad results for ambient light in scattering. Works better with bubbles than addition. --- crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl index f4c7cfb1b..3178c4170 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl @@ -62,7 +62,7 @@ void ComputeFoam(half i_foam, float2 i_worldXZUndisplaced, float2 i_worldXZ, hal half bubbleFoamTexValue = BubbleFoamTexture(i_worldXZ, i_worldXZUndisplaced, i_n, i_view, lodVal); o_bubbleCol = (half3)bubbleFoamTexValue * _FoamBubbleColor.rgb * saturate(i_foam * _WaveFoamBubblesCoverage) * AmbientLight(); #if defined(VERTEXLIGHT_ON) - o_bubbleCol += lightsCol; + o_bubbleCol *= lightsCol; #endif // VERTEXLIGHT_ON // White foam on top, with black-point fading From f1c6e56c0ecec9bc057cb82d5330da9d09a481a6 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Sat, 28 Dec 2019 17:50:16 +1100 Subject: [PATCH 4/7] Add/improve shader param comments --- crest/Assets/Crest/Crest/Shaders/Ocean.shader | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index a54409030..db7e6b366 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -169,8 +169,9 @@ Shader "Crest/Ocean" _LightsSubSurfaceBase("Sub Surface Base Mul", Range(0.0, 4.0)) = 1.0 // Strength of specular lighting response _LightsSpecular("Specular", Range(0.0, 1000.0)) = 31.0 - // Light strength on foam + // Light strength on foam. Also depends on _WaveFoamLightScale. _LightsScaleWaveFoam("Foam Lights Scale", Range(0.0, 1000.0)) = 5.0 + // Controls harshness of Fresnel behaviour for lights. _LightsFresnelPower("Fresnel Power", Range(1.0, 20.0)) = 10.0 [Header(Debug Options)] From ad80a36175062f084ed6eb42e4c5e78fa77c26a0 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Tue, 15 Dec 2020 09:42:10 -0800 Subject: [PATCH 5/7] Re index texcoords --- .../Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index 1fbb798a9..3fcad8e82 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -92,7 +92,7 @@ Shader "Crest/Underwater Curtain" half4 grabPos : TEXCOORD2; float3 positionWS : TEXCOORD3; #if defined(VERTEXLIGHT_ON) - half4 uvLightsAtten : TEXCOORD10; + half4 uvLightsAtten : TEXCOORD4; #endif // VERTEXLIGHT_ON UNITY_VERTEX_OUTPUT_STEREO From e261fbae12cf3fa48a0a3534359184b86aef84dc Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Tue, 15 Dec 2020 10:30:27 -0800 Subject: [PATCH 6/7] Apply depth fog to SSS vertex light colour --- crest/Assets/Crest/Crest/Shaders/Ocean.shader | 10 +++++++++- .../Crest/Shaders/Underwater/UnderwaterCurtain.shader | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index 64627d2f1..41120aab0 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -576,9 +576,17 @@ Shader "Crest/Ocean" #endif // _FOAM_ON // Compute color of ocean - in-scattered light + refracted scene + half3 sssLightsCol = lightsCol; + #if defined(VERTEXLIGHT_ON) + if (underwater) + { + // Apply depth fog to light colour. Otherwise, there will light patches visible from far away. + sssLightsCol *= saturate(exp(-_DepthFogDensity.xyz * pixelZ)); + } + #endif const float baseCascadeScale = _CrestCascadeData[0]._scale; const float meshScaleLerp = instanceData._meshScaleLerp; - half3 scatterCol = ScatterColour(input.lodAlpha_worldXZUndisplaced_oceanDepth.w, _WorldSpaceCameraPos, lightDir, view, shadow.x, underwater, true, sss, lightsCol, meshScaleLerp, baseCascadeScale, cascadeData0); + half3 scatterCol = ScatterColour(input.lodAlpha_worldXZUndisplaced_oceanDepth.w, _WorldSpaceCameraPos, lightDir, view, shadow.x, underwater, true, sss, sssLightsCol, meshScaleLerp, baseCascadeScale, cascadeData0); half3 col = OceanEmission(view, n_pixel, lightDir, input.grabPos, pixelZ, uvDepth, sceneZ, sceneZ01, bubbleCol, _Normals, underwater, scatterCol, cascadeData0, cascadeData1); // Light that reflects off water surface diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index 3fcad8e82..5ab1095a9 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -228,8 +228,8 @@ Shader "Crest/Underwater Curtain" // Calculate vertex lights colour #if defined(VERTEXLIGHT_ON) lightsCol = CalculateVertexLightsColor(input.uvLightsAtten, input.positionWS, _LightTextureB0); - // Decrease intensity so it isn't overwhelming - lightsCol *= 0.5; + // Apply depth fog to light colour. Otherwise, there will light patches visible from far away. + lightsCol *= exp(-_DepthFogDensity.xyz * sceneZ); #endif // VERTEXLIGHT_ON const float meshScaleLerp = _CrestPerCascadeInstanceData[_LD_SliceIndex]._meshScaleLerp; From f5520cbaca0b557ae544c444604b6df86d93f488 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Tue, 15 Dec 2020 10:31:26 -0800 Subject: [PATCH 7/7] Housekeeping --- crest/Assets/Crest/Crest/Shaders/Ocean.shader | 2 +- .../Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index 41120aab0..934939534 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -522,7 +522,7 @@ Shader "Crest/Ocean" float sceneZ = LinearEyeDepth(sceneZ01); float3 lightDir = WorldSpaceLightDir(input.worldPos); - half3 lightsCol = 0; + half3 lightsCol = 0.0; // Calculate #if defined(VERTEXLIGHT_ON) diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index 5ab1095a9..9608a8f02 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -223,7 +223,7 @@ Shader "Crest/Underwater Curtain" const float depth = 0.0; const half shadow = 1.0; - half3 lightsCol = 0; + half3 lightsCol = 0.0; // Calculate vertex lights colour #if defined(VERTEXLIGHT_ON)