summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x3ner.shader1
-rwxr-xr-xbrdf.cginc2
-rw-r--r--glitter.cginc21
-rwxr-xr-xglobals.cginc1
-rwxr-xr-xlighting.cginc43
5 files changed, 30 insertions, 38 deletions
diff --git a/3ner.shader b/3ner.shader
index 0910996..5cc10be 100755
--- a/3ner.shader
+++ b/3ner.shader
@@ -661,7 +661,6 @@ Shader "yum_food/3ner"
[ThryToggle(_GLITTER)] _Glitter_Enabled("Enable", Float) = 0
_Glitter_Amount("Amount", Range(0, 1)) = 0.5
_Glitter_Roughness("Roughness", Range(0.001, 0.1)) = 0.01
- _Glitter_IBL_Roughness("IBL Roughness", Range(0.001, 1)) = 0.01
_Glitter_Tint("Tint", Color) = (1, 1, 1, 1)
[HideInInspector] m_end_Glitter("Glitter", Float) = 0
//endex
diff --git a/brdf.cginc b/brdf.cginc
index a76ee13..219a04b 100755
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -236,7 +236,7 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
float3 indirect_f_glitter = F_Schlick(data.glitter.indirect_LoH, 0.15f, 1.0f);
float indirect_g_glitter = G_GGXSmith(pbr.roughness, data.glitter.indirect_NoL, data.common.NoV);
float3 indirect_specular_glitter = (data.glitter.indirect_D * indirect_g_glitter)
- * indirect_f_glitter * data.glitter.indirect_specular * data.glitter.indirect_NoL
+ * indirect_f_glitter * max(0, data.indirect.L00) * data.glitter.indirect_NoL
* _Glitter_Tint;
// No spec ao for glitter, please.
specular += indirect_specular_glitter * remainder;
diff --git a/glitter.cginc b/glitter.cginc
index 676b902..022b176 100644
--- a/glitter.cginc
+++ b/glitter.cginc
@@ -14,9 +14,7 @@
* 1. Syntax changes required to translate GLSL to HLSL.
* 2. Stylistic preferences, like using "1" or "1.0" instead of "1.".
* 3. The `GetGlitterLighting` function, which populates data required for
- * IBL. The original paper only discusses analytic lighting. For IBL, you
- * also need the micro-normal to figure out which part of the cubemap to
- * sample.
+ * indirect glitter. The original paper only discusses analytic lighting.
*
* @article{KPT:2025:Glinty,
* title = {Evaluating and Sampling Glinty NDFs in Constant Time},
@@ -171,6 +169,7 @@ float3 disk_to_ndf_ggx(float2 v_disk, float alpha) {
return float3(alpha * hemi.xy, hemi.z) / denom;
}
+// Algorithm 1 from Kemppinen et. al.
float D_Kemppinen(float3 h, float alpha, float glint_alpha, float2 uv,
float2x2 uv_J, float N, float filter_size, out float3 micro_normal) {
float res = sqrt(N);
@@ -235,9 +234,6 @@ struct LightGlitter {
float direct_D;
float indirect_D;
- float3 indirect_specular;
- float3 indirect_dir;
- float3 indirect_H;
float indirect_NoL;
float indirect_LoH;
};
@@ -246,7 +242,7 @@ struct LightGlitter {
LightGlitter GetGlitterLighting(
float glitter_amount, float glitter_roughness,
float2 uv, float3x3 tbn, float roughness,
- float3 normal, float3 V, float3 direct_H, float3 indirect_H) {
+ float3 normal, float3 V, float3 direct_H, float3 indirect_dir) {
LightGlitter g;
const float glitter_filter_size = 0.7f;
float2x2 uv_J = uv_ellipsoid(transpose(float2x2(ddx(uv), ddy(uv))));
@@ -259,19 +255,16 @@ LightGlitter GetGlitterLighting(
uv, uv_J, N, glitter_filter_size, direct_micro_normal);
// Indirect
+ float3 indirect_H = normalize(V + indirect_dir);
float3 indirect_H_tangent = mul(indirect_H, transpose(tbn));
- float3 indirect_micro_normal; // used to sample cubemap
+ float3 indirect_micro_normal; // unused, but required by D_Kemppinen
g.indirect_D = D_Kemppinen(indirect_H_tangent, roughness, glitter_roughness,
uv, uv_J, N, glitter_filter_size, indirect_micro_normal);
- // Normal vector is the halfway vector in IBL.
- g.indirect_H = normalize(mul(indirect_micro_normal, tbn));
- g.indirect_dir = reflect(-V, g.indirect_H);
- g.indirect_NoL = max(1e-4, dot(normal, g.indirect_dir));
- g.indirect_LoH = max(1e-4, dot(g.indirect_dir, g.indirect_H));
+ g.indirect_NoL = max(1e-4, dot(normal, indirect_dir));
+ g.indirect_LoH = max(1e-4, dot(indirect_dir, indirect_H));
return g;
}
#endif
#endif // __GLITTER_INC
-
diff --git a/globals.cginc b/globals.cginc
index 2b9c163..88fb663 100755
--- a/globals.cginc
+++ b/globals.cginc
@@ -155,7 +155,6 @@ int _Details_UV_Channel;
#if defined(_GLITTER)
float _Glitter_Amount;
float _Glitter_Roughness;
-float _Glitter_IBL_Roughness;
float3 _Glitter_Tint;
#endif // _GLITTER
diff --git a/lighting.cginc b/lighting.cginc
index 52c9cac..b6d3f8e 100755
--- a/lighting.cginc
+++ b/lighting.cginc
@@ -42,6 +42,15 @@ float3 getIndirectSpecular(v2f i, float perceptual_roughness, float3 view_dir, f
return env_refl;
}
+float3 getAverageSHDirection(float3 L1r, float3 L1g, float3 L1b, float3 fallback_dir) {
+ float3 raw_dir = L1r + L1g + L1b;
+ float raw_dir_len = length(raw_dir);
+ if (abs(raw_dir_len) < 1e-3) {
+ return fallback_dir;
+ }
+ return raw_dir / raw_dir_len;
+}
+
// Geomerics SH evaluation
// https://community.arm.com/cfs-file/__key/telligent-evolution-components-attachments/01-2066-00-00-00-01-27-70/Simplifying_2D00_Spherical_2D00_Harmonics_2D00_for_2D00_Lighting.pdf
float shEvaluateDiffuseL1Geomerics(float L0, float3 L1, float3 n) {
@@ -139,22 +148,11 @@ float4 getIndirectDiffuse(v2f i, Pbr pbr, inout LightData light) {
#endif
#if defined(_SHADOWS) || defined(_SSFD)
- float3x3 mat = float3x3(
- light.indirect.L01r,
- light.indirect.L01g,
- light.indirect.L01b
- );
- // Multiply unit vector by L1 matrix to get vector pointing in direction of
- // light.
- float3 raw_dir = mul(mat, float3(1,1,1));
- float raw_dir_len = length(raw_dir);
- float3 dom_dir = normalize(mul(mat, float3(1,1,1)));
- if (abs(raw_dir_len) < 1e-3) {
- dom_dir = light.direct.dir;
- } else {
- dom_dir = raw_dir;
- }
- dom_dir = normalize(dom_dir);
+ float3 dom_dir = getAverageSHDirection(
+ light.indirect.L01r,
+ light.indirect.L01g,
+ light.indirect.L01b,
+ light.direct.dir);
light.indirect.diffuse_dominant_dir = dom_dir;
#endif
@@ -266,11 +264,14 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) {
data.indirect.diffuse = getIndirectDiffuse(i, pbr, data);
data.indirect.specular = getIndirectSpecular(i, pbr.roughness_perceptual, view_dir, data.indirect.dir, data.indirect.diffuse);
#if defined(_GLITTER)
+ float3 glitter_indirect_dir = getAverageSHDirection(
+ data.indirect.L01r,
+ data.indirect.L01g,
+ data.indirect.L01b,
+ data.indirect.dir);
data.glitter = GetGlitterLighting(_Glitter_Amount, _Glitter_Roughness,
i.uv01.xy, pbr.tbn, pbr.roughness,
- pbr.normal, data.common.V, data.direct.H, data.indirect.H);
- data.glitter.indirect_specular = getIndirectSpecular(i, _Glitter_IBL_Roughness,
- view_dir, data.glitter.indirect_dir, data.indirect.diffuse);
+ pbr.normal, data.common.V, data.direct.H, glitter_indirect_dir);
#endif
data.common.ao = getAO(i);
@@ -299,9 +300,9 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) {
data.indirect.specular = HSVtoRGB(tmpHSV);
#if defined(_GLITTER)
- tmpHSV = RGBtoHSV(data.glitter.indirect_specular);
+ tmpHSV = RGBtoHSV(data.indirect.L00);
tmpHSV[2] = clamp(tmpHSV[2], 0, _Brightness_Clamp_Max);
- data.glitter.indirect_specular = HSVtoRGB(tmpHSV);
+ data.indirect.L00 = HSVtoRGB(tmpHSV);
#endif
#if defined(_CLEARCOAT)