summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--2ner.shader36
-rw-r--r--features.cginc16
-rw-r--r--globals.cginc26
-rw-r--r--tessellation.cginc158
-rw-r--r--yum_pbr.cginc41
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;