summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-03-31 21:50:39 -0700
committeryum <yum.food.vr@gmail.com>2025-03-31 21:50:39 -0700
commit2dfd6322587eb095a5a4f7b22d70e1abcc14d5e3 (patch)
tree76b6f84628e07c722b74ce58b34e70d672e9541d
parent3f1915bbd0e6176e625c484cf24a460cc88bfeac (diff)
Overhaul wrapped lighting
Now: * k=0 -> lambertian * k=0.5 -> half lambertian * k=1.0 -> flat All three points should be energy conserving, but I haven't done the actual analysis yet.
-rw-r--r--2ner.cginc1
-rw-r--r--2ner.shader9
-rw-r--r--audiolink.cginc2
-rw-r--r--globals.cginc3
-rw-r--r--math.cginc19
-rw-r--r--shatter_wave.cginc7
-rw-r--r--tessellation.cginc35
-rw-r--r--vertex_domain_warping.cginc7
-rw-r--r--yum_brdf.cginc12
-rw-r--r--yum_lighting.cginc6
10 files changed, 68 insertions, 33 deletions
diff --git a/2ner.cginc b/2ner.cginc
index 4b74666..d8bc010 100644
--- a/2ner.cginc
+++ b/2ner.cginc
@@ -274,6 +274,7 @@ float4 frag(v2f i
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
UNITY_APPLY_FOG(_unity_fogCoord, lit.rgb);
+
return lit;
#elif defined(SHADOW_CASTER_PASS) || defined(MASKED_STENCIL1_PASS) || defined(MASKED_STENCIL2_PASS) || defined(MASKED_STENCIL3_PASS) || defined(MASKED_STENCIL4_PASS)
return 0;
diff --git a/2ner.shader b/2ner.shader
index e43c4f5..42fc187 100644
--- a/2ner.shader
+++ b/2ner.shader
@@ -573,17 +573,20 @@ Shader "yum_food/2ner"
//ifex _Vertex_Domain_Warping_Enabled==0
[HideInInspector] m_start_Vertex_Domain_Warping("Vertex domain warping", Float) = 0
- [ThryToggle(_VERTEX_DOMAIN_WARPING)]_Vertex_Domain_Warping_Enabled("Enable", Float) = 0
+ [ThryToggle(_VERTEX_DOMAIN_WARPING)] _Vertex_Domain_Warping_Enabled("Enable", Float) = 0
_Vertex_Domain_Warping_Noise("Noise", 3D) = "black" {}
_Vertex_Domain_Warping_Strength("Strength", Float) = 0.10
_Vertex_Domain_Warping_Scale("Scale", Float) = 1.0
_Vertex_Domain_Warping_Octaves("Octaves", Float) = 1.0
_Vertex_Domain_Warping_Speed("Speed", Float) = 1.0
+ //ifex _Vertex_Domain_Warping_Audiolink_Enabled==0
[HideInInspector] m_start_Vertex_Domain_Warping_Audiolink("Audiolink", Float) = 0
[ThryToggle(_VERTEX_DOMAIN_WARPING_AUDIOLINK)] _Vertex_Domain_Warping_Audiolink_Enabled("Enable", Float) = 0
- _Vertex_Domain_Warping_Audiolink_VU_Factors("VU factors (strength|scale|unused|unused)", Vector) = (1, 1, 0, 0)
+ _Vertex_Domain_Warping_Audiolink_VU_Strength_Factor("VU strength factor", Float) = 1.0
+ _Vertex_Domain_Warping_Audiolink_VU_Scale_Factor("VU scale factor", Float) = 1.0
[HideInInspector] m_end_Vertex_Domain_Warping_Audiolink("Audiolink", Float) = 0
- [HideInInspector] m_end_Vertex_Domain_Warping("Vertex domain warping", Float) = 0
+ //endex
+ [HideInInspector] m_end_Vertex_Domain_Warping("Vertex domain warping", Float) = 0
//endex
//ifex _UV_Domain_Warping_Enabled==0
diff --git a/audiolink.cginc b/audiolink.cginc
index c5a202a..bb8de54 100644
--- a/audiolink.cginc
+++ b/audiolink.cginc
@@ -1,7 +1,7 @@
#ifndef __AUDIOLINK
#define __AUDIOLINK
-#if defined(_SHATTER_WAVE_AUDIOLINK)
+#if defined(_SHATTER_WAVE_AUDIOLINK) || defined(_VERTEX_DOMAIN_WARPING_AUDIOLINK)
#include "Third_Party/AudioLink.cginc"
#endif
diff --git a/globals.cginc b/globals.cginc
index 2578e3a..62bbdee 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -295,7 +295,8 @@ float _Vertex_Domain_Warping_Speed;
#endif // _VERTEX_DOMAIN_WARPING
#if defined(_VERTEX_DOMAIN_WARPING_AUDIOLINK)
-float4 _Vertex_Domain_Warping_Audiolink_VU_Factors;
+float _Vertex_Domain_Warping_Audiolink_VU_Strength_Factor;
+float _Vertex_Domain_Warping_Audiolink_VU_Scale_Factor;
#endif // _VERTEX_DOMAIN_WARPING_AUDIOLINK
#if defined(_UV_DOMAIN_WARPING)
diff --git a/math.cginc b/math.cginc
index 8d404d9..bccb206 100644
--- a/math.cginc
+++ b/math.cginc
@@ -15,9 +15,24 @@ float pow5(float x)
return (tmp * tmp) * x;
}
-float wrapNoL(float NoL, float factor) {
+float wrapNoL(float NoL, float k) {
+#if 0
// https://www.iro.umontreal.ca/~derek/files/jgt_wrap_final.pdf
- return pow(max(1E-4, (NoL + factor) / (1 + factor)), 1 + factor);
+ return pow(max(1E-4, (NoL + k) / (1 + k)), 1 + k);
+#else
+ float k_sq = k * k;
+ float b = max(0, lerp(NoL, 1.0, k));
+ float p = -6.0 * k_sq + 5.0 * k + 1.0;
+ // Using the formula
+ float F = pow(b, p);
+
+ // Approximate integral of NoL with respect to theta
+ float I = 0.7856 * k_sq - 0.2148 * k + 1.0;
+
+ float G = F / max(I, 1E-6);
+
+ return G;
+#endif
}
float halfLambertianNoL(float NoL) {
diff --git a/shatter_wave.cginc b/shatter_wave.cginc
index f86a6ac..d65741f 100644
--- a/shatter_wave.cginc
+++ b/shatter_wave.cginc
@@ -15,7 +15,7 @@ void shatterWaveVert(inout float3 objPos, float3 objNormal, float3 objTangent) {
float3 wave_axis2 = normalize(_Shatter_Wave_Direction2);
float3 wave_axis3 = normalize(_Shatter_Wave_Direction3);
float4x3 wave_axes = float4x3(wave_axis0, wave_axis1, wave_axis2, wave_axis3);
-
+
float4 projDots = mul(wave_axes, objPos);
// Equivalent code:
// float4 projDots = float4(
@@ -24,7 +24,7 @@ void shatterWaveVert(inout float3 objPos, float3 objNormal, float3 objTangent) {
// dot(objPos, wave_axis2),
// dot(objPos, wave_axis3)
// );
-
+
float4x3 objPos_proj = float4x3(
projDots.x * wave_axis0,
projDots.y * wave_axis1,
@@ -67,6 +67,9 @@ void shatterWaveVert(inout float3 objPos, float3 objNormal, float3 objTangent) {
_Shatter_Wave_Time_Offset * _Shatter_Wave_Period -
_Time[0] * _Shatter_Wave_Speed * .3,
_Shatter_Wave_Period) - _Shatter_Wave_Period * 0.5;
+ } else {
+ wave_t = _Time[0] * _Shatter_Wave_Speed;
+ wave_t = fmod(wave_t + _Shatter_Wave_Time_Offset * _Shatter_Wave_Period, _Shatter_Wave_Period) - _Shatter_Wave_Period * 0.5;
}
#else
float4 wave_t = _Time[0] * _Shatter_Wave_Speed;
diff --git a/tessellation.cginc b/tessellation.cginc
index 30c3c63..af4bd3b 100644
--- a/tessellation.cginc
+++ b/tessellation.cginc
@@ -3,6 +3,7 @@
#include "globals.cginc"
#include "interpolators.cginc"
+#include "math.cginc"
#include "shatter_wave.cginc"
//ifex _Tessellation_Enabled==0
@@ -34,16 +35,20 @@ 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)
float max_displacement = _Tessellation_Heightmap_Scale * 0.5 + _Tessellation_Heightmap_Offset;
+#else
+ float max_displacement = 0;
+#endif
float3 p0d = patch[0].objPos.xyz + patch[0].normal.xyz * max_displacement;
float3 p1d = patch[1].objPos.xyz + patch[1].normal.xyz * max_displacement;
float3 p2d = patch[2].objPos.xyz + patch[2].normal.xyz * max_displacement;
- float4 p0_clipPos = UnityObjectToClipPos(float4(patch[0].objPos.xyz, 1));
- float4 p1_clipPos = UnityObjectToClipPos(float4(patch[1].objPos.xyz, 1));
- float4 p2_clipPos = UnityObjectToClipPos(float4(patch[2].objPos.xyz, 1));
- float4 p0d_clipPos = UnityObjectToClipPos(float4(p0d, 1));
- float4 p1d_clipPos = UnityObjectToClipPos(float4(p1d, 1));
- float4 p2d_clipPos = UnityObjectToClipPos(float4(p2d, 1));
+ float4 p0_clipPos = UnityObjectToClipPos(patch[0].objPos.xyz);
+ float4 p1_clipPos = UnityObjectToClipPos(patch[1].objPos.xyz);
+ float4 p2_clipPos = UnityObjectToClipPos(patch[2].objPos.xyz);
+ float4 p0d_clipPos = UnityObjectToClipPos(p0d);
+ float4 p1d_clipPos = UnityObjectToClipPos(p1d);
+ float4 p2d_clipPos = UnityObjectToClipPos(p2d);
float3 p0_ndc = p0_clipPos.xyz / p0_clipPos.w;
float3 p1_ndc = p1_clipPos.xyz / p1_clipPos.w;
float3 p2_ndc = p2_clipPos.xyz / p2_clipPos.w;
@@ -58,7 +63,7 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) {
(p0d_ndc.x > -1 && p0d_ndc.x < 1 && p0d_ndc.y > -1 && p0d_ndc.y < 1 && p0d_clipPos.w > 0) ||
(p1d_ndc.x > -1 && p1d_ndc.x < 1 && p1d_ndc.y > -1 && p1d_ndc.y < 1 && p1d_clipPos.w > 0) ||
(p2d_ndc.x > -1 && p2d_ndc.x < 1 && p2d_ndc.y > -1 && p2d_ndc.y < 1 && p2d_clipPos.w > 0);
- factor = lerp(0, factor, on_screen);
+ factor = lerp(1, factor, on_screen);
}
#else
float factor = 1;
@@ -74,7 +79,7 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) {
[UNITY_domain("tri")]
[UNITY_outputcontrolpoints(3)]
[UNITY_outputtopology("triangle_cw")]
-[UNITY_partitioning("integer")]
+[UNITY_partitioning("fractional_odd")]
[UNITY_patchconstantfunc("patch_constant")]
v2f hull(
InputPatch<v2f, 3> patch,
@@ -113,11 +118,21 @@ v2f domain(
#endif
#if defined(_TESSELLATION_HEIGHTMAP)
- float height = _Tessellation_Heightmap.SampleLevel(linear_repeat_s,
- o.uv01.xy * _Tessellation_Heightmap_ST.xy, 0).r *
+#if 1
+ float raw_noise = _Tessellation_Heightmap.SampleLevel(linear_repeat_s,
+ o.uv01.xy * _Tessellation_Heightmap_ST.xy, 0).r;
+ float height = raw_noise *
_Tessellation_Heightmap_Scale +
_Tessellation_Heightmap_Offset +
_Tessellation_Heightmap_Scale * -0.5;
+#else
+ // For whatever reason, it seems like the texture read is initially
+ // returning a small number when the mesh spawns in VRC. A procedural noise
+ // works around the issue.
+ float height = rand2(o.uv01.xy) * _Tessellation_Heightmap_Scale +
+ _Tessellation_Heightmap_Offset +
+ _Tessellation_Heightmap_Scale * -0.5;
+#endif
#if defined(OUTLINE_PASS)
o.objPos.xyz += -o.normal * height;
#else
diff --git a/vertex_domain_warping.cginc b/vertex_domain_warping.cginc
index 3bbc5cd..29c500a 100644
--- a/vertex_domain_warping.cginc
+++ b/vertex_domain_warping.cginc
@@ -2,6 +2,7 @@
#define __VERTEX_DOMAIN_WARPING_INC
#include "audiolink.cginc"
+#include "features.cginc"
#include "globals.cginc"
#include "math.cginc"
@@ -10,14 +11,14 @@ float3 domainWarpVertexPosition(float3 objPos) {
float speed = _Vertex_Domain_Warping_Speed;
float scale = _Vertex_Domain_Warping_Scale;
float strength = _Vertex_Domain_Warping_Strength;
- float octaves = _Vertex_Domain_Warping_Octaves;
+ uint octaves = (uint) _Vertex_Domain_Warping_Octaves;
#if defined(_VERTEX_DOMAIN_WARPING_AUDIOLINK)
[branch]
if (AudioLinkIsAvailable()) {
float vu = AudioLinkData(ALPASS_FILTEREDVU_INTENSITY + uint2(0, 0));
- strength += vu * _Vertex_Domain_Warping_Audiolink_VU_Factors.x;
- scale += vu * _Vertex_Domain_Warping_Audiolink_VU_Factors.y;
+ strength += vu * _Vertex_Domain_Warping_Audiolink_VU_Strength_Factor;
+ scale += vu * _Vertex_Domain_Warping_Audiolink_VU_Scale_Factor;
}
#endif
diff --git a/yum_brdf.cginc b/yum_brdf.cginc
index 9bc01bf..8b0d659 100644
--- a/yum_brdf.cginc
+++ b/yum_brdf.cginc
@@ -68,7 +68,7 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
// Use a proper diffuse BRDF term instead of raw albedo
float3 Fd = pbr.albedo / PI;
Fd *= light.attenuation;
-
+
#if defined(_MATERIAL_TYPE_CLOTH_SUBSURFACE)
// Energy conservative wrap diffuse for subsurface scattering
float wrap_diffuse = saturate((NoL + 0.5) / 2.25);
@@ -76,15 +76,15 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
// Apply subsurface color
Fd *= saturate(_Cloth_Subsurface_Color + NoL);
#endif
-
+
// Cloth specular BRDF
float3 Fr = specularLobe(pbr, 0.04, h, LoH, NoH, NoV, NoL_wrapped_s);
-
+
#if defined(_MATERIAL_TYPE_CLOTH_SUBSURFACE)
// No need to multiply by NoL when using subsurface scattering
- direct_cloth = (Fd + Fr * NoL) * light.direct * _Cloth_Direct_Multiplier;
+ direct_cloth = (Fd + Fr * NoL_wrapped_d) * light.direct * _Cloth_Direct_Multiplier;
#else
- direct_cloth = (Fd + Fr) * NoL * light.direct * _Cloth_Direct_Multiplier;
+ direct_cloth = (Fd + Fr) * NoL_wrapped_d * light.direct * _Cloth_Direct_Multiplier;
#endif
}
#endif
@@ -105,7 +105,7 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
float3 Fd = pbr.albedo / PI;
Fd *= (1.0 - pbr.metallic) * light.attenuation;
float3 Fr = specularLobe(pbr, f0, h, LoH, NoH, NoV, NoL_wrapped_s);
-
+
float3 color = Fd * NoL_wrapped_d + Fr * energy_compensation * NoL_wrapped_s;
direct_standard = color * light.direct;
}
diff --git a/yum_lighting.cginc b/yum_lighting.cginc
index 5e627d5..3af5654 100644
--- a/yum_lighting.cginc
+++ b/yum_lighting.cginc
@@ -202,11 +202,7 @@ YumLighting GetYumLighting(v2f i, YumPbr pbr) {
// normalize has no visibile impact in test scene
light.view_dir = -i.eyeVec.xyz;
-#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
- light.dir = normalize((_WorldSpaceLightPos0 - i.worldPos).xyz);
-#else
- light.dir = _WorldSpaceLightPos0;
-#endif
+ light.dir = getDirectLightDirection(i);
light.direct = _LightColor0.rgb;
// TODO filament's spherical harmonics look nicer than this.