From 525e179dcb03bcc509ee7f2a362764db6de7d940 Mon Sep 17 00:00:00 2001 From: Huw Bowles Date: Sun, 19 Jan 2020 11:21:25 +0000 Subject: [PATCH 1/2] AnimWavesAddFromTex - generate displacements from heights Uses forward differences to compute derivates and displace proportionally. Similar to how the disps are generated from the dynamic wave sim. --- .../OceanInputs/AnimWavesAddFromTex.shader | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader b/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader index 493690bea..5cf4c1ed4 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader +++ b/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader @@ -9,15 +9,14 @@ Shader "Crest/Inputs/Animated Waves/Add From Texture" _MainTex("Texture", 2D) = "white" {} _Strength( "Strength", float ) = 1 [Toggle] _HeightsOnly("Heights Only", Float) = 1 + [Toggle] _GenerateDisplacementsFromHeights("Generate Displacements From Heights", Float) = 0 + _GenerateDisplacementStrength("Generate Displacement Strength", Range(0, 10)) = 1 [Toggle] _SSSFromAlpha("Sub Surface Scattering (SSS) from Alpha", Float) = 0 _SSSStrength("SSS Strength", Float) = 0.5 } SubShader { - // base simulation runs on the Geometry queue, before this shader. - // this shader adds interaction forces on top of the simulation result. - Tags { "Queue" = "Transparent" } Blend One One Pass @@ -28,15 +27,16 @@ Shader "Crest/Inputs/Animated Waves/Add From Texture" #pragma shader_feature _HEIGHTSONLY_ON #pragma shader_feature _SSSFROMALPHA_ON + #pragma shader_feature _GENERATEDISPLACEMENTSFROMHEIGHTS_ON #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; - + float4 _MainTex_TexelSize; float _Strength; float _SSSStrength; - + float _GenerateDisplacementStrength; float _Weight; struct Attributes @@ -48,13 +48,15 @@ Shader "Crest/Inputs/Animated Waves/Add From Texture" struct Varyings { float4 positionCS : SV_POSITION; - float2 uv : TEXCOORD0; + float3 positionWS : TEXCOORD0; + float2 uv : TEXCOORD1; }; Varyings Vert(Attributes input) { Varyings o; o.positionCS = UnityObjectToClipPos(input.positionOS); + o.positionWS = mul(unity_ObjectToWorld, float4(input.positionOS, 1.0)).xyz; o.uv = TRANSFORM_TEX(input.uv, _MainTex); return o; } @@ -67,7 +69,15 @@ Shader "Crest/Inputs/Animated Waves/Add From Texture" half4 texSample = tex2D(_MainTex, input.uv); #if _HEIGHTSONLY_ON - displacement.y = texSample.x * _Strength; + displacement.y = texSample.x; + +#if _GENERATEDISPLACEMENTSFROMHEIGHTS_ON + float height_x = tex2D(_MainTex, input.uv + float2(_MainTex_TexelSize.x, 0.0)); + float height_z = tex2D(_MainTex, input.uv + float2(0.0, _MainTex_TexelSize.y)); + displacement.x = _GenerateDisplacementStrength * (height_x - displacement.y) / ddx(input.positionWS.x); + displacement.z = _GenerateDisplacementStrength * (height_z - displacement.y) / ddy(input.positionWS.z); +#endif + displacement *= _Strength; #else displacement.xyz = texSample.xyz * _Strength; #endif From 3549880394b83e93deb37ec2a142007d56a91544 Mon Sep 17 00:00:00 2001 From: Huw Bowles Date: Sun, 19 Jan 2020 12:04:17 +0000 Subject: [PATCH 2/2] Docs / refactor --- .../Shaders/OceanInputs/AnimWavesAddFromTex.shader | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader b/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader index 5cf4c1ed4..8197f42a3 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader +++ b/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesAddFromTex.shader @@ -69,24 +69,30 @@ Shader "Crest/Inputs/Animated Waves/Add From Texture" half4 texSample = tex2D(_MainTex, input.uv); #if _HEIGHTSONLY_ON + // Texture represents heights, not 3D displacements displacement.y = texSample.x; #if _GENERATEDISPLACEMENTSFROMHEIGHTS_ON + // Generate horizontal displacement from derivatives of height + + // These derivatives aren't strictly correct - they assume there is a roughly 1:1 correspondance between + // texture sampling density (via _MainTex_TexelSize.x) and output sampling density (via ddx(input.positionWS.x)). + // I couldn't find a nice/cheap way to compute texel density (i.e. maintex texel size in world), so i'll leave + // it to a scale factor. float height_x = tex2D(_MainTex, input.uv + float2(_MainTex_TexelSize.x, 0.0)); float height_z = tex2D(_MainTex, input.uv + float2(0.0, _MainTex_TexelSize.y)); displacement.x = _GenerateDisplacementStrength * (height_x - displacement.y) / ddx(input.positionWS.x); displacement.z = _GenerateDisplacementStrength * (height_z - displacement.y) / ddy(input.positionWS.z); #endif - displacement *= _Strength; #else - displacement.xyz = texSample.xyz * _Strength; + displacement.xyz = texSample.xyz; #endif #if _SSSFROMALPHA_ON sss = texSample.x * _SSSStrength; #endif - return _Weight * half4(displacement, sss); + return _Weight * half4(_Strength * displacement, sss); } ENDCG