summaryrefslogtreecommitdiff
path: root/intermediate
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-11 22:26:10 +1100
committerquou <quou@disroot.org>2025-01-11 22:26:10 +1100
commit306c6318a32a9af351daaa60d2cc082e45e30dd4 (patch)
treef0f662a4c8d75e7afef30684ce13b57e30bde35a /intermediate
parent64b32afb4e1fed0259b67a47e8b8ff30e4e20635 (diff)
mip the specular cube properly
Diffstat (limited to 'intermediate')
-rw-r--r--intermediate/mip_spec.glsl72
1 files changed, 69 insertions, 3 deletions
diff --git a/intermediate/mip_spec.glsl b/intermediate/mip_spec.glsl
index bddcbb0..519fee0 100644
--- a/intermediate/mip_spec.glsl
+++ b/intermediate/mip_spec.glsl
@@ -18,10 +18,27 @@ type: vec2
name: uv
type: vec2
+[struct]
+name: Face
+[variable]
+name: dir
+type: vec3
+[variable]
+name: roughness
+type: float
+[variable]
+name: up
+type: vec3
+
+[cbuffer]
+name: c_face
+type: Face
+stage: fragment
+
[texture]
name: src
stage: fragment
-dimension: 2
+dimension: cube
[target]
name: colour
@@ -36,9 +53,58 @@ void main() {
#endif
#ifdef FRAGMENT_SHADER
+float ri(uint bits) {
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xaaaaaaaau) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xccccccccu) >> 2u);
+ bits = ((bits & 0x0f0f0f0fu) << 4u) | ((bits & 0xf0f0f0f0u) >> 4u);
+ bits = ((bits & 0x00ff00ffu) << 8u) | ((bits & 0xff00ff00u) >> 8u);
+ return float(bits) * 2.3283064365386963e-10;
+}
+
+vec2 hammersley(uint i, uint n) {
+ return vec2(float(i) / float(n), ri(i));
+}
+
+#define pi 3.14159265358979323846
+
+vec3 importance_sample_ggx(vec2 xi, float rough, vec3 n) {
+ float a = rough * rough;
+ float phi = 2 * pi * xi.x;
+ float ct = sqrt((1 - xi.y) / (1 + (a * a - 1) * xi.y));
+ float st = sqrt(1 - ct * ct);
+ vec3 h;
+ h.x = st * cos(phi);
+ h.y = st * sin(phi);
+ h.z = ct;
+ vec3 up = abs(n.z) < 0.999 ? vec3(0, 0, 1) : vec3(1, 0, 0);
+ vec3 tx = normalize(cross(up, n));
+ vec3 ty = cross(n, tx);
+ return tx * h.x + ty * h.y + n * h.z;
+}
+
+vec3 prefilter_env(float rough, vec3 n) {
+ vec3 c = 0.0.xxx;
+ int i, samples = 32;
+ float w = 1.0 / float(samples);
+ for (i = 0; i < samples; i++) {
+ vec2 coord = hammersley(i, samples);
+ vec3 s = importance_sample_ggx(coord, rough, n);
+ vec3 l = 2.0 * dot(n, s) * s - n;
+ c += (textureLod(src, l, 0.0).rgb * max(dot(n, l), 0.0)) * w;
+ }
+ return c;
+}
+
void main() {
- vec2 uv = interpolator.uv;
- colour = texture(src, uv);
+ vec2 uv = interpolator.uv * 2.0 - 1.0;
+ vec3 n = c_face.dir;
+ vec3 u = c_face.up;
+ vec3 p1 = normalize(cross(n, u));
+ vec3 p2 = normalize(cross(n, p1));
+ vec3 uvw = uv.x * p1 + uv.y * p2;
+ n = normalize(n + uvw);
+ colour = vec4(prefilter_env(c_face.roughness, n), 1.0);
}
#endif