summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-07-29 14:13:09 -0700
committeryum <yum.food.vr@gmail.com>2025-07-29 14:13:09 -0700
commiteba91b479fb6476fed06b13906d7805f43f879b6 (patch)
tree0075c78dc884d579c884b67cd36372f8af725e39
parentf1ccfe1d74846df120be984cb09d45ec7e17810c (diff)
Add "gradient xz normals" feature
Take in the gradient of a 2D heightmap (y is up) in one or more channels, sum them up, then convert to normal.
-rw-r--r--2ner.shader52
-rw-r--r--features.cginc28
-rw-r--r--globals.cginc33
-rw-r--r--tessellation.cginc4
-rw-r--r--yum_brdf.cginc6
-rw-r--r--yum_pbr.cginc48
6 files changed, 166 insertions, 5 deletions
diff --git a/2ner.shader b/2ner.shader
index e886828..3834d5f 100644
--- a/2ner.shader
+++ b/2ner.shader
@@ -953,6 +953,58 @@ Shader "yum_food/2ner"
//endex
[HideInInspector] m_end_Decals("Decals", Float) = 0
+ [HideInInspector] m_start_XZ_Gradient_Normals("XZ Gradient Normals", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS)] _XZ_Gradient_Normals_Enabled("Enable", Float) = 0
+ //ifex _XZ_Gradient_Normals_0_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_0("Gradient 0", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_0)] _XZ_Gradient_Normals_0_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_0("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_0("Gradient 0", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_1_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_1("Gradient 1", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_1)] _XZ_Gradient_Normals_1_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_1("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_1("Gradient 1", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_2_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_2("Gradient 2", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_2)] _XZ_Gradient_Normals_2_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_2("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_2("Gradient 2", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_3_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_3("Gradient 3", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_3)] _XZ_Gradient_Normals_3_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_3("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_3("Gradient 3", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_4_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_4("Gradient 4", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_4)] _XZ_Gradient_Normals_4_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_4("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_4("Gradient 4", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_5_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_5("Gradient 5", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_5)] _XZ_Gradient_Normals_5_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_5("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_5("Gradient 5", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_6_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_6("Gradient 6", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_6)] _XZ_Gradient_Normals_6_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_6("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_6("Gradient 6", Float) = 0
+ //endex
+ //ifex _XZ_Gradient_Normals_7_Enabled==0
+ [HideInInspector] m_start_XZ_Gradient_Normals_7("Gradient 7", Float) = 0
+ [ThryToggle(_XZ_GRADIENT_NORMALS_7)] _XZ_Gradient_Normals_7_Enabled("Enable", Float) = 0
+ _XZ_Gradient_Normals_7("Texture", 2D) = "black" {}
+ [HideInInspector] m_end_XZ_Gradient_Normals_7("Gradient 7", Float) = 0
+ //endex
+ [HideInInspector] m_end_XZ_Gradient_Normals("XZ Gradient Normals", Float) = 0
+
[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 8e6ebcd..3e02789 100644
--- a/features.cginc
+++ b/features.cginc
@@ -240,6 +240,34 @@
#pragma shader_feature_local _DECAL7_EMISSIONS_PROXIMITY
//endex
+//ifex _XZ_Gradient_Normals_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS
+//endex
+//ifex _XZ_Gradient_Normals_0_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_0
+//endex
+//ifex _XZ_Gradient_Normals_1_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_1
+//endex
+//ifex _XZ_Gradient_Normals_2_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_2
+//endex
+//ifex _XZ_Gradient_Normals_3_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_3
+//endex
+//ifex _XZ_Gradient_Normals_4_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_4
+//endex
+//ifex _XZ_Gradient_Normals_5_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_5
+//endex
+//ifex _XZ_Gradient_Normals_6_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_6
+//endex
+//ifex _XZ_Gradient_Normals_7_Enabled==0
+#pragma shader_feature_local _XZ_GRADIENT_NORMALS_7
+//endex
+
//ifex _3D_SDF_Enabled==0
#pragma shader_feature_local _3D_SDF
//endex
diff --git a/globals.cginc b/globals.cginc
index 0017758..110ad98 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -333,6 +333,39 @@ DECLARE_DECAL_VARIABLES(6)
DECLARE_DECAL_VARIABLES(7)
#endif
+#if defined(_XZ_GRADIENT_NORMALS_0)
+texture2D _XZ_Gradient_Normals_0;
+float4 _XZ_Gradient_Normals_0_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_1)
+texture2D _XZ_Gradient_Normals_1;
+float4 _XZ_Gradient_Normals_1_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_2)
+texture2D _XZ_Gradient_Normals_2;
+float4 _XZ_Gradient_Normals_2_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_3)
+texture2D _XZ_Gradient_Normals_3;
+float4 _XZ_Gradient_Normals_3_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_4)
+texture2D _XZ_Gradient_Normals_4;
+float4 _XZ_Gradient_Normals_4_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_5)
+texture2D _XZ_Gradient_Normals_5;
+float4 _XZ_Gradient_Normals_5_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_6)
+texture2D _XZ_Gradient_Normals_6;
+float4 _XZ_Gradient_Normals_6_ST;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_7)
+texture2D _XZ_Gradient_Normals_7;
+float4 _XZ_Gradient_Normals_7_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 23df0d4..7e8c790 100644
--- a/tessellation.cginc
+++ b/tessellation.cginc
@@ -35,7 +35,7 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) {
// un-transformed and maximally transformed locations. Technically we could
// miss an intersection in the middle, but I haven't noticed any visible
// popping with this approach.
-#if defined(_TESSELLATION_HEIGHTMAP) && (defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3))
+#if defined(_TESSELLATION) && (defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3))
float max_displacement = max(
max(_Tessellation_Heightmap_0_Scale * 0.5 + _Tessellation_Heightmap_0_Offset,
_Tessellation_Heightmap_1_Scale * 0.5 + _Tessellation_Heightmap_1_Offset),
@@ -123,7 +123,7 @@ v2f domain(
#endif
#endif
-#if (defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3))
+#if defined(_TESSELLATION) && (defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3))
float height = 0;
#if defined(_TESSELLATION_HEIGHTMAP_0)
float heightmap_0_sample = _Tessellation_Heightmap_0.SampleLevel(bilinear_repeat_s,
diff --git a/yum_brdf.cginc b/yum_brdf.cginc
index daa6793..2d07440 100644
--- a/yum_brdf.cginc
+++ b/yum_brdf.cginc
@@ -126,11 +126,11 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
// Compute proper diffuse color with metallic blending
float3 diffuseColor = computeDiffuseColor(pbr.albedo, pbr.metallic);
-
+
// Fd_Burley already includes 1/PI, so multiply by PI to match Unity intensities
float3 Fd = diffuseColor * Fd_Burley(pbr.roughness, NoV, NoL_wrapped_d, LoH) * PI;
Fd *= light.attenuation * pbr.ao;
-
+
// Multiply by PI to match Unity intensities (same as Filament's implementation)
float3 Fr = specularLobe(pbr, f0, h, LoH, NoH, NoV, NoL_wrapped_s) * PI * light.attenuation;
@@ -173,7 +173,7 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
// Use proper diffuse color calculation
float3 diffuseColor = computeDiffuseColor(pbr.albedo, pbr.metallic);
float3 Fd = diffuseColor * light.diffuse * (1.0 - E) * pbr.ao;
-
+
float3 Fr = E * light.specular * specularSingleBounceAO;
indirect_standard = Fr + Fd;
diff --git a/yum_pbr.cginc b/yum_pbr.cginc
index 8df2fde..5877022 100644
--- a/yum_pbr.cginc
+++ b/yum_pbr.cginc
@@ -27,6 +27,50 @@ void propagateRoughness(in float smoothness, out float roughness_perceptual, out
roughness = roughness_perceptual * roughness_perceptual;
}
+#if defined(_XZ_GRADIENT_NORMALS)
+void applyGradientNormals(v2f i, inout YumPbr pbr) {
+ float2 uv = i.uv01.xy;
+
+ float2 gradient = 0;
+#if defined(_XZ_GRADIENT_NORMALS_0)
+ float2 g0_uv = uv * _XZ_Gradient_Normals_0_ST.xy;
+ gradient += _XZ_Gradient_Normals_0.SampleLevel(bilinear_repeat_s, g0_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_1)
+ float2 g1_uv = uv * _XZ_Gradient_Normals_1_ST.xy;
+ gradient += _XZ_Gradient_Normals_1.SampleLevel(bilinear_repeat_s, g1_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_2)
+ float2 g2_uv = uv * _XZ_Gradient_Normals_2_ST.xy;
+ gradient += _XZ_Gradient_Normals_2.SampleLevel(bilinear_repeat_s, g2_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_3)
+ float2 g3_uv = uv * _XZ_Gradient_Normals_3_ST.xy;
+ gradient += _XZ_Gradient_Normals_3.SampleLevel(bilinear_repeat_s, g3_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_4)
+ float2 g4_uv = uv * _XZ_Gradient_Normals_4_ST.xy;
+ gradient += _XZ_Gradient_Normals_4.SampleLevel(bilinear_repeat_s, g4_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_5)
+ float2 g5_uv = uv * _XZ_Gradient_Normals_5_ST.xy;
+ gradient += _XZ_Gradient_Normals_5.SampleLevel(bilinear_repeat_s, g5_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_6)
+ float2 g6_uv = uv * _XZ_Gradient_Normals_6_ST.xy;
+ gradient += _XZ_Gradient_Normals_6.SampleLevel(bilinear_repeat_s, g6_uv, 0).rg;
+#endif
+#if defined(_XZ_GRADIENT_NORMALS_7)
+ float2 g7_uv = uv * _XZ_Gradient_Normals_7_ST.xy;
+ gradient += _XZ_Gradient_Normals_7.SampleLevel(bilinear_repeat_s, g7_uv, 0).rg;
+#endif
+
+ // Technically I think this is in object space but uhhh I'll deal with that later idk.
+ float3 gradient_normal = normalize(float3(-gradient.x, 1.0f, -gradient.y));
+ pbr.normal = gradient_normal;
+}
+#endif
+
YumPbr GetYumPbr(v2f i, float3x3 tangentToWorld) {
YumPbr result = (YumPbr)0;
@@ -149,6 +193,10 @@ YumPbr GetYumPbr(v2f i, float3x3 tangentToWorld) {
result.normal = normalize(mul(normal_tangent, tangentToWorld));
+#if defined(_XZ_GRADIENT_NORMALS)
+ applyGradientNormals(i, result);
+#endif
+
#if (defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS)) && defined(_GLITTER)
GlitterParams glitter_p;
glitter_p.color = _Glitter_Color;