summaryrefslogtreecommitdiffstats
path: root/glitter.cginc
diff options
context:
space:
mode:
Diffstat (limited to 'glitter.cginc')
-rw-r--r--glitter.cginc59
1 files changed, 45 insertions, 14 deletions
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
-