diff options
| -rw-r--r-- | 2ner.shader | 36 | ||||
| -rw-r--r-- | features.cginc | 16 | ||||
| -rw-r--r-- | globals.cginc | 26 | ||||
| -rw-r--r-- | tessellation.cginc | 158 | ||||
| -rw-r--r-- | yum_pbr.cginc | 41 |
5 files changed, 218 insertions, 59 deletions
diff --git a/2ner.shader b/2ner.shader index c66f470..a016f8b 100644 --- a/2ner.shader +++ b/2ner.shader @@ -1019,6 +1019,42 @@ Shader "yum_food/2ner" [HideInInspector] m_end_Gradient_Normals("Gradient Normals", Float) = 0 //endex + //ifex _Sea_Foam_Enabled==0 + [HideInInspector] m_start_Sea_Foam("Sea foam", Float) = 0 + [ThryToggle(_SEA_FOAM)] _Sea_Foam_Enabled("Enable", Float) = 0 + _Sea_Foam_Color("Color", Color) = (1, 1, 1, 1) + _Sea_Foam_Roughness("Roughness", Float) = 0.85 + _Sea_Foam_Lambda("Lambda", Range(0, 4)) = 1 + _Sea_Foam_Power("Power", Range(0, 50)) = 1 + _Sea_Foam_Factor("Factor", Range(0, 2)) = 1 + _Sea_Foam_Bias("Bias", Range(-5, 5)) = 0 + //ifex _Sea_Foam_0_Enabled==0 + [HideInInspector] m_start_Sea_Foam_0("Sea foam 0", Float) = 0 + [ThryToggle(_SEA_FOAM_0)] _Sea_Foam_0_Enabled("Enable", Float) = 0 + _Sea_Foam_0_Slope("(dfx/dx, dfy/dy, 0, dfx/dy)", 2D) = "black" {} + [HideInInspector] m_end_Sea_Foam_0("Sea foam 0", Float) = 0 + //endex + //ifex _Sea_Foam_1_Enabled==0 + [HideInInspector] m_start_Sea_Foam_1("Sea foam 1", Float) = 0 + [ThryToggle(_SEA_FOAM_1)] _Sea_Foam_1_Enabled("Enable", Float) = 0 + _Sea_Foam_1_Slope("(dfx/dx, dfy/dy, 0, dfx/dy)", 2D) = "black" {} + [HideInInspector] m_end_Sea_Foam_1("Sea foam 1", Float) = 0 + //endex + //ifex _Sea_Foam_2_Enabled==0 + [HideInInspector] m_start_Sea_Foam_2("Sea foam 2", Float) = 0 + [ThryToggle(_SEA_FOAM_2)] _Sea_Foam_2_Enabled("Enable", Float) = 0 + _Sea_Foam_2_Slope("(dfx/dx, dfy/dy, 0, dfx/dy)", 2D) = "black" {} + [HideInInspector] m_end_Sea_Foam_2("Sea foam 2", Float) = 0 + //endex + //ifex _Sea_Foam_3_Enabled==0 + [HideInInspector] m_start_Sea_Foam_3("Sea foam 3", Float) = 0 + [ThryToggle(_SEA_FOAM_3)] _Sea_Foam_3_Enabled("Enable", Float) = 0 + _Sea_Foam_3_Slope("(dfx/dx, dfy/dy, 0, dfx/dy)", 2D) = "black" {} + [HideInInspector] m_end_Sea_Foam_3("Sea foam 3", Float) = 0 + //endex + [HideInInspector] m_end_Sea_Foam("Sea foam", Float) = 0 + //endex + [HideInInspector] m_start_Color_Correction("Color correction", Float) = 0 //ifex _Oklch_Correction_Enabled==0 [HideInInspector] m_start_Oklch_Correction("Oklch", Float) = 0 diff --git a/features.cginc b/features.cginc index b090113..80029bb 100644 --- a/features.cginc +++ b/features.cginc @@ -268,6 +268,22 @@ #pragma shader_feature_local _GRADIENT_NORMALS_3_HORIZONTAL //endex +//ifex _Sea_Foam_Enabled==0 +#pragma shader_feature_local _SEA_FOAM +//endex +//ifex _Sea_Foam_0_Enabled==0 +#pragma shader_feature_local _SEA_FOAM_0 +//endex +//ifex _Sea_Foam_1_Enabled==0 +#pragma shader_feature_local _SEA_FOAM_1 +//endex +//ifex _Sea_Foam_2_Enabled==0 +#pragma shader_feature_local _SEA_FOAM_2 +//endex +//ifex _Sea_Foam_3_Enabled==0 +#pragma shader_feature_local _SEA_FOAM_3 +//endex + //ifex _3D_SDF_Enabled==0 #pragma shader_feature_local _3D_SDF //endex diff --git a/globals.cginc b/globals.cginc index 2b65fc0..9fdf417 100644 --- a/globals.cginc +++ b/globals.cginc @@ -369,6 +369,32 @@ texture2D _Gradient_Normals_3_Horizontal; float4 _Gradient_Normals_3_Horizontal_ST;
#endif
+#if defined(_SEA_FOAM)
+float4 _Sea_Foam_Color;
+float _Sea_Foam_Roughness;
+float _Sea_Foam_Lambda;
+float _Sea_Foam_Power;
+float _Sea_Foam_Factor;
+float _Sea_Foam_Bias;
+#endif
+
+#if defined(_SEA_FOAM_0)
+texture2D _Sea_Foam_0_Slope;
+float4 _Sea_Foam_0_Slope_ST;
+#endif
+#if defined(_SEA_FOAM_1)
+texture2D _Sea_Foam_1_Slope;
+float4 _Sea_Foam_1_Slope_ST;
+#endif
+#if defined(_SEA_FOAM_2)
+texture2D _Sea_Foam_2_Slope;
+float4 _Sea_Foam_2_Slope_ST;
+#endif
+#if defined(_SEA_FOAM_3)
+texture2D _Sea_Foam_3_Slope;
+float4 _Sea_Foam_3_Slope_ST;
+#endif
+
#if defined(_VERTEX_DOMAIN_WARPING)
texture3D _Vertex_Domain_Warping_Noise;
float _Vertex_Domain_Warping_Strength;
diff --git a/tessellation.cginc b/tessellation.cginc index fce9979..24d53ab 100644 --- a/tessellation.cginc +++ b/tessellation.cginc @@ -13,6 +13,79 @@ struct tess_factors { float inside : SV_InsideTessFactor; }; +bool isInViewFrustum(float4 clipPos, float radius) { + return -clipPos.w - radius < clipPos.x && clipPos.x < clipPos.w + radius && + -clipPos.w - radius < clipPos.y && clipPos.y < clipPos.w + radius && + -clipPos.w - radius < clipPos.z && clipPos.z < clipPos.w + radius; +} + +#if defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3) || defined(_TESSELLATION_HEIGHTMAP_4) || defined(_TESSELLATION_HEIGHTMAP_5) || defined(_TESSELLATION_HEIGHTMAP_6) || defined(_TESSELLATION_HEIGHTMAP_7) +#define _TESSELLATION_HEIGHTMAP +#endif + +float4 applyHeightmap(float4 objPos, float2 uv, float3 normal, float3 tangent, float3 binormal) { +#if defined(_TESSELLATION) && defined(_TESSELLATION_HEIGHTMAP) + float3 height = 0; +#if defined(_TESSELLATION_HEIGHTMAP_0) + float3 heightmap_0_sample = _Tessellation_Heightmap_0.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_0_ST.xy, 0); + height += heightmap_0_sample * _Tessellation_Heightmap_0_Scale + _Tessellation_Heightmap_0_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_1) + float3 heightmap_1_sample = _Tessellation_Heightmap_1.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_1_ST.xy, 0); + height += heightmap_1_sample * _Tessellation_Heightmap_1_Scale + _Tessellation_Heightmap_1_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_2) + float3 heightmap_2_sample = _Tessellation_Heightmap_2.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_2_ST.xy, 0); + height += heightmap_2_sample * _Tessellation_Heightmap_2_Scale + _Tessellation_Heightmap_2_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_3) + float3 heightmap_3_sample = _Tessellation_Heightmap_3.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_3_ST.xy, 0); + height += heightmap_3_sample * _Tessellation_Heightmap_3_Scale + _Tessellation_Heightmap_3_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_4) + float3 heightmap_4_sample = _Tessellation_Heightmap_4.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_4_ST.xy, 0); + height += heightmap_4_sample * _Tessellation_Heightmap_4_Scale + _Tessellation_Heightmap_4_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_5) + float3 heightmap_5_sample = _Tessellation_Heightmap_5.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_5_ST.xy, 0); + height += heightmap_5_sample * _Tessellation_Heightmap_5_Scale + _Tessellation_Heightmap_5_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_6) + float3 heightmap_6_sample = _Tessellation_Heightmap_6.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_6_ST.xy, 0); + height += heightmap_6_sample * _Tessellation_Heightmap_6_Scale + _Tessellation_Heightmap_6_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_7) + float3 heightmap_7_sample = _Tessellation_Heightmap_7.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_7_ST.xy, 0); + height += heightmap_7_sample * _Tessellation_Heightmap_7_Scale + _Tessellation_Heightmap_7_Offset; +#endif + +#if defined(_TESSELLATION_HEIGHTMAP_WORLD_SPACE) + objPos.xyz += mul(unity_WorldToObject, height).xyz; +#else +#if defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) + float3 heightmap_direction = mul(transpose(-float3x3(normal, tangent, binormal)), _Tessellation_Heightmap_Direction_Control_Vector); +#elif defined(OUTLINE_PASS) && !defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) + float3 heightmap_direction = -normal; +#elif !defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) + float3 heightmap_direction = mul(transpose(float3x3(normal, tangent, binormal)), _Tessellation_Heightmap_Direction_Control_Vector); +#else + float3 heightmap_direction = normal; +#endif + objPos.xyz += heightmap_direction * height; +#endif + +#endif // _TESSELLATION_HEIGHTMAP + return objPos; +} + tess_factors patch_constant(InputPatch<v2f, 3> patch) { tess_factors f; #if defined(_TESSELLATION) @@ -32,6 +105,31 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) { #else float factor = 1; #endif + +#if defined(_TESSELLATION_HEIGHTMAP) + [branch] + if (factor > 3) { + // Scuffed occlusion culling. Need to know what the position will be after displacement + // in order to do it right. "Scuffed" because we repeat work :/ this same transform gets + // applied in the domain shader. This isn't so bad if we assume that we're tessellating + // at a relatively high factor. + float3 p0newObjPos = applyHeightmap(patch[0].objPos, patch[0].uv01.xy, patch[0].normal, patch[0].tangent, patch[0].binormal); + float3 p1newObjPos = applyHeightmap(patch[1].objPos, patch[1].uv01.xy, patch[1].normal, patch[1].tangent, patch[1].binormal); + float3 p2newObjPos = applyHeightmap(patch[2].objPos, patch[2].uv01.xy, patch[2].normal, patch[2].tangent, patch[2].binormal); + float4 p0newClipPos = UnityObjectToClipPos(p0newObjPos); + float4 p1newClipPos = UnityObjectToClipPos(p1newObjPos); + float4 p2newClipPos = UnityObjectToClipPos(p2newObjPos); + // Dirty hack to prevent objects that are currently outside the view frustum, + // but which are after displacement, from being culled. + float radius = 0.3; + bool inViewFrustum0 = isInViewFrustum(p0newClipPos, radius); + bool inViewFrustum1 = isInViewFrustum(p1newClipPos, radius); + bool inViewFrustum2 = isInViewFrustum(p2newClipPos, radius); + bool inViewFrustum = inViewFrustum0 || inViewFrustum1 || inViewFrustum2; + factor = inViewFrustum ? factor : 1; + } +#endif + f.edge[0] = factor; f.edge[1] = factor; f.edge[2] = factor; @@ -82,65 +180,7 @@ v2f domain( #endif #endif -#if defined(_TESSELLATION) && (defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3) || defined(_TESSELLATION_HEIGHTMAP_4) || defined(_TESSELLATION_HEIGHTMAP_5) || defined(_TESSELLATION_HEIGHTMAP_6) || defined(_TESSELLATION_HEIGHTMAP_7)) - float3 height = 0; -#if defined(_TESSELLATION_HEIGHTMAP_0) - float3 heightmap_0_sample = _Tessellation_Heightmap_0.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_0_ST.xy, 0); - height += heightmap_0_sample * _Tessellation_Heightmap_0_Scale + _Tessellation_Heightmap_0_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_1) - float3 heightmap_1_sample = _Tessellation_Heightmap_1.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_1_ST.xy, 0); - height += heightmap_1_sample * _Tessellation_Heightmap_1_Scale + _Tessellation_Heightmap_1_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_2) - float3 heightmap_2_sample = _Tessellation_Heightmap_2.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_2_ST.xy, 0); - height += heightmap_2_sample * _Tessellation_Heightmap_2_Scale + _Tessellation_Heightmap_2_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_3) - float3 heightmap_3_sample = _Tessellation_Heightmap_3.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_3_ST.xy, 0); - height += heightmap_3_sample * _Tessellation_Heightmap_3_Scale + _Tessellation_Heightmap_3_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_4) - float3 heightmap_4_sample = _Tessellation_Heightmap_4.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_4_ST.xy, 0); - height += heightmap_4_sample * _Tessellation_Heightmap_4_Scale + _Tessellation_Heightmap_4_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_5) - float3 heightmap_5_sample = _Tessellation_Heightmap_5.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_5_ST.xy, 0); - height += heightmap_5_sample * _Tessellation_Heightmap_5_Scale + _Tessellation_Heightmap_5_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_6) - float3 heightmap_6_sample = _Tessellation_Heightmap_6.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_6_ST.xy, 0); - height += heightmap_6_sample * _Tessellation_Heightmap_6_Scale + _Tessellation_Heightmap_6_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_7) - float3 heightmap_7_sample = _Tessellation_Heightmap_7.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_7_ST.xy, 0); - height += heightmap_7_sample * _Tessellation_Heightmap_7_Scale + _Tessellation_Heightmap_7_Offset; -#endif - -#if defined(_TESSELLATION_HEIGHTMAP_WORLD_SPACE) - o.objPos.xyz += mul(unity_WorldToObject, height).xyz; -#else -#if defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) - float3 heightmap_direction = mul(transpose(-float3x3(o.normal, o.tangent, o.binormal)), _Tessellation_Heightmap_Direction_Control_Vector); -#elif defined(OUTLINE_PASS) && !defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) - float3 heightmap_direction = -o.normal; -#elif !defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) - float3 heightmap_direction = mul(transpose(float3x3(o.normal, o.tangent, o.binormal)), _Tessellation_Heightmap_Direction_Control_Vector); -#else - float3 heightmap_direction = o.normal; -#endif - o.objPos.xyz += heightmap_direction * height; -#endif - -#endif // _TESSELLATION_HEIGHTMAP + o.objPos = applyHeightmap(o.objPos, o.uv01.xy, o.normal, o.tangent, o.binormal); o.pos = UnityObjectToClipPos(o.objPos); o.worldPos = mul(unity_ObjectToWorld, o.objPos).xyz; diff --git a/yum_pbr.cginc b/yum_pbr.cginc index ec5bedb..5baff19 100644 --- a/yum_pbr.cginc +++ b/yum_pbr.cginc @@ -99,6 +99,44 @@ void applyGradientNormals(v2f i, inout YumPbr pbr) { } #endif +#if defined(_SEA_FOAM) +void applySeaFoam(v2f i, inout YumPbr pbr) { + float2 uv = i.uv01.xy; + + float4 slope = 0; + + #if defined(_SEA_FOAM_0) + slope += _Sea_Foam_0_Slope.SampleLevel(bilinear_repeat_s, uv * _Sea_Foam_0_Slope_ST.xy, 0); + #endif + #if defined(_SEA_FOAM_1) + slope += _Sea_Foam_1_Slope.SampleLevel(bilinear_repeat_s, uv * _Sea_Foam_1_Slope_ST.xy, 0); + #endif + #if defined(_SEA_FOAM_2) + slope += _Sea_Foam_2_Slope.SampleLevel(bilinear_repeat_s, uv * _Sea_Foam_2_Slope_ST.xy, 0); + #endif + #if defined(_SEA_FOAM_3) + slope += _Sea_Foam_3_Slope.SampleLevel(bilinear_repeat_s, uv * _Sea_Foam_3_Slope_ST.xy, 0); + #endif + + float dfx_dx = slope[0]; + float dfy_dy = slope[1]; + float dfx_dy = slope[3]; + + float Jxx = 1 + dfx_dx * _Sea_Foam_Lambda; + float Jyy = 1 + dfy_dy * _Sea_Foam_Lambda; + float Jxy = dfx_dy * _Sea_Foam_Lambda; + + float det = Jxx * Jyy - Jxy * Jxy; + float foam_contribution = det; + foam_contribution += _Sea_Foam_Bias; + foam_contribution = saturate(foam_contribution); + + pbr.albedo.rgb = lerp(pbr.albedo.rgb, _Sea_Foam_Color.rgb, foam_contribution * _Sea_Foam_Color.a); + pbr.smoothness = lerp(pbr.smoothness, 1.0f - _Sea_Foam_Roughness, foam_contribution); + propagateRoughness(pbr.smoothness, pbr.roughness_perceptual, pbr.roughness); +} +#endif + YumPbr GetYumPbr(v2f i, float3x3 tangentToWorld) { YumPbr result = (YumPbr)0; @@ -224,6 +262,9 @@ YumPbr GetYumPbr(v2f i, float3x3 tangentToWorld) { #if defined(_GRADIENT_NORMALS) applyGradientNormals(i, result); #endif +#if defined(_SEA_FOAM) + applySeaFoam(i, result); +#endif #if (defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS)) && defined(_GLITTER) GlitterParams glitter_p; |
