diff options
Diffstat (limited to 'intermediate/mip_spec.glsl')
-rw-r--r-- | intermediate/mip_spec.glsl | 72 |
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 |