diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-29 16:10:25 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-29 16:10:25 -0700 |
| commit | 4ed9ed040230f62a1144936df36afddf4a5208bb (patch) | |
| tree | aa607cd9e63c3d9e169f387463a3f5676f7370fd | |
| parent | a9217eb6c67282ac2451f1eafcedca04a8c5e564 (diff) | |
Roughly integrate glitter into brdf
| -rwxr-xr-x | 3ner.cginc | 2 | ||||
| -rwxr-xr-x | brdf.cginc | 19 | ||||
| -rwxr-xr-x | features.cginc | 4 | ||||
| -rw-r--r-- | glitter.cginc | 59 | ||||
| -rwxr-xr-x | globals.cginc | 5 |
5 files changed, 71 insertions, 18 deletions
@@ -322,7 +322,7 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace latePbr(i, light_data, pbr); BrdfData bd; - float4 lit = brdf(pbr, light_data, bd); + float4 lit = brdf(i, pbr, light_data, bd); return apply_debug_view(i, pbr, light_data, bd, lit); } @@ -101,7 +101,7 @@ float G_Estevez(float roughness, float NoL, float NoV) { return 1.0 / ((1.0 + lambda_l + lambda_v) * 4.0 * NoL * NoV); } -float4 brdf(Pbr pbr, LightData data, out BrdfData bd) { +float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { bd = (BrdfData)0; float3 specular = 0; float3 diffuse = 0; @@ -178,13 +178,26 @@ float4 brdf(Pbr pbr, LightData data, out BrdfData bd) { direct_diffuse = max(0, direct_diffuse); diffuse += direct_diffuse; #else + float3 direct_energy = energy_comp; + bd.direct_g = G_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV); +#if defined(_GLITTER) + float2 glitter_uv = frac(i.uv01.xy); + float2x2 glitter_uv_J = uv_ellipsoid(mat2_from_cols(ddx(glitter_uv), ddy(glitter_uv))); + float3 H_tangent = mul(data.direct.H, transpose(pbr.tbn)); + const float glitter_filter_size = 0.7f; + float glitter_N = 8.0e5f * pow(10.0f, _Glitter_Amount * 6.0f - 2.0f); + bd.direct_f = F_Schlick(data.direct.LoH, 0.96f, 1.0f); + bd.direct_d = D_Kemppinen(H_tangent, pbr.roughness, _Glitter_Roughness, + glitter_uv, glitter_uv_J, glitter_N, glitter_filter_size); + direct_energy = 1.0f; +#else bd.direct_f = F_Schlick(data.direct.LoH, f0_color, f90); bd.direct_d = D_GGX(pbr.roughness, data.direct.NoH); - bd.direct_g = G_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV); +#endif float3 direct_specular = (bd.direct_d * bd.direct_g) * bd.direct_f; direct_specular *= data.direct.color * data.direct.NoL; - direct_specular *= energy_comp; + direct_specular *= direct_energy; direct_specular *= remainder; specular += direct_specular; diff --git a/features.cginc b/features.cginc index 93cc8e2..42202ff 100755 --- a/features.cginc +++ b/features.cginc @@ -67,6 +67,10 @@ #pragma shader_feature_local _DETAILS //endex +//ifex _Glitter_Enabled==0 +#pragma shader_feature_local _GLITTER +//endex + //ifex _Vertex_Deformation_Enabled==0 #pragma shader_feature_local _VERTEX_DEFORMATION #pragma shader_feature_local _VERTEX_DEFORMATION_FRAGMENT_NORMALS diff --git a/glitter.cginc b/glitter.cginc index 39b735b..2744d6b 100644 --- a/glitter.cginc +++ b/glitter.cginc @@ -21,6 +21,16 @@ float2 lambert(float3 v) { return v.xy / sqrt(1 + v.z); } +// Rebuild GLSL mat2 column semantics explicitly in HLSL. +float2 mat2_col(float2x2 m, uint i) { + return float2(m[0][i], m[1][i]); +} + +float2x2 mat2_from_cols(float2 c0, float2 c1) { + return float2x2(c0.x, c1.x, + c0.y, c1.y); +} + // v is a microfacet normal that has been squished according to alpha, a // roughness parameter. float3 ndf_to_disk_ggx(float3 v, float alpha) { @@ -37,26 +47,31 @@ float3 ndf_to_disk_ggx(float3 v, float alpha) { // Computes (M^T M)^-1 float2x2 inv_quadratic(float2x2 M) { float D = determinant(M); - float A = dot(M[0] / D, M[0] / D); - float B = -dot(M[0] / D, M[1] / D); - float C = dot(M[1] / D, M[1] / D); - return float2x2(C, B, B, A); + float2 c0 = mat2_col(M, 0) / D; + float2 c1 = mat2_col(M, 1) / D; + float A = dot(c0, c0); + float B = -dot(c0, c1); + float C = dot(c1, c1); + return mat2_from_cols(float2(C, B), float2(B, A)); } float2x2 uv_ellipsoid(float2x2 uv_J) { float2x2 Q = inv_quadratic(transpose(uv_J)); - float tr = 0.5 * (Q[0][0] + Q[1][1]); + float2 q0 = mat2_col(Q, 0); + float2 q1 = mat2_col(Q, 1); + float tr = 0.5 * (q0.x + q1.y); float D = sqrt(max(0.0, tr * tr - determinant(Q))); float l1 = tr - D; float l2 = tr + D; - float2 v1 = float2(l1 - Q[1][1], Q[0][1]); - float2 v2 = float2(Q[1][0], l2 - Q[0][0]); + float2 v1 = float2(l1 - q1.y, q0.y); + float2 v2 = float2(q1.x, l2 - q0.x); float2 n = 1.f/sqrt(float2(l1, l2)); - return float2x2(normalize(v1)*n.x, normalize(v2)*n.y); + return mat2_from_cols(normalize(v1) * n.x, normalize(v2) * n.y); } float QueryLod(float2x2 uv_J, float filter_size) { - float s0 = length(uv_J[0]), s1 = length(uv_J[1]); + float s0 = length(mat2_col(uv_J, 0)); + float s1 = length(mat2_col(uv_J, 1)); return log2(max(s0, s1) * filter_size) + pow(2.0, filter_size); } @@ -64,11 +79,28 @@ float normal(float2x2 cov, float2 x) { return exp(-.5 * dot(x, mul(inverse(cov), x))) / (sqrt(determinant(cov)) * 2.0 * PI); } -float Rand2D(float2 x, float2 y, float l, uint i) { +uint2 shuffle(uint2 v) { + v = v * 1664525u + 1013904223u; + v.x += v.y * 1664525u; + v.y += v.x * 1664525u; + + v = v ^ (v>>16u); + + v.x += v.y * 1664525u; + v.y += v.x * 1664525u; + v = v ^ (v>>16u); + return v; +} + +float2 rand(uint2 v) { + return float2(shuffle(v)) * pow(0.5, 32.0); +} + +float2 Rand2D(float2 x, float2 y, float l, uint i) { uint2 ux = asuint(x); uint2 uy = asuint(y); uint ul = asuint(l); - return hash22_fast((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u)); + return rand((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u)); } float Rand1D(float2 x, float2 y, float l, uint i) { @@ -102,7 +134,7 @@ float compensation(float2 x_a, float2x2 sigma_a, float res_a) { return containing - explicitly_evaluated; } -float ndf(float3 h, float alpha, float glint_alpha, float2 uv, float2x2 uv_J, float N, float filter_size) { +float D_Kemppinen(float3 h, float alpha, float glint_alpha, float2 uv, float2x2 uv_J, float N, float filter_size) { float res = sqrt(N); float2 x_s = uv; float3 x_a_and_d = ndf_to_disk_ggx(h, alpha); @@ -121,7 +153,7 @@ float ndf(float3 h, float alpha, float glint_alpha, float2 uv, float2x2 uv_J, fl float res_a = pow(2., l); float2x2 uv_J2 = filter_size * uv_J; - float2x2 sigma_s = uv_J2 * transpose(uv_J2); + float2x2 sigma_s = mul(uv_J2, transpose(uv_J2)); float2x2 sigma_a = d * pow(glint_alpha, 2.) * float2x2(1., .0, .0, 1.); @@ -149,4 +181,3 @@ float ndf(float3 h, float alpha, float glint_alpha, float2 uv, float2x2 uv_J, fl } #endif // __GLITTER_INC - diff --git a/globals.cginc b/globals.cginc index 95d16ee..770a497 100755 --- a/globals.cginc +++ b/globals.cginc @@ -152,6 +152,11 @@ float4 _DetailMask_ST; int _Details_UV_Channel; #endif // _DETAILS +#if defined(_GLITTER) +float _Glitter_Amount; +float _Glitter_Roughness; +#endif // _GLITTER + #if defined(_UV_SCROLL) float2 _UV_Scroll_Speed; #endif // _UV_SCROLL |
