summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x3ner.cginc2
-rwxr-xr-xbrdf.cginc19
-rwxr-xr-xfeatures.cginc4
-rw-r--r--glitter.cginc59
-rwxr-xr-xglobals.cginc5
5 files changed, 71 insertions, 18 deletions
diff --git a/3ner.cginc b/3ner.cginc
index 502fe8e..d7184a4 100755
--- a/3ner.cginc
+++ b/3ner.cginc
@@ -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);
}
diff --git a/brdf.cginc b/brdf.cginc
index de222e7..8bd0061 100755
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -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