载入中...
搜索中...
未找到
ReflectionProbeWgsl.h
浏览该文件的文档.
1#pragma once
2
4
6inline constexpr const char *kReflectionProbeFilterWgsl = R"wgsl(
7struct Params { data: vec4f } // face, roughness, diffuse, sampleCount
8@group(0) @binding(0) var sourceCube: texture_cube<f32>;
9@group(0) @binding(1) var sourceSampler: sampler;
10@group(0) @binding(2) var<uniform> params: Params;
11
12struct VSOut { @builtin(position) position: vec4f, @location(0) uv: vec2f };
13
14@vertex fn vs_main(@builtin(vertex_index) index: u32) -> VSOut {
15 let positions = array<vec2f, 3>(vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));
16 var out: VSOut;
17 out.position = vec4f(positions[index], 0.0, 1.0);
18 out.uv = positions[index] * 0.5 + 0.5;
19 return out;
20}
21
22fn faceDirection(face: i32, u: f32, v: f32) -> vec3f {
23 if (face == 0) { return normalize(vec3f(1.0, -v, -u)); }
24 if (face == 1) { return normalize(vec3f(-1.0, -v, u)); }
25 if (face == 2) { return normalize(vec3f(u, 1.0, v)); }
26 if (face == 3) { return normalize(vec3f(u, -1.0, -v)); }
27 if (face == 4) { return normalize(vec3f(u, -v, 1.0)); }
28 return normalize(vec3f(-u, -v, -1.0));
29}
30
31fn radicalInverse(bitsIn: u32) -> f32 {
32 var bits = bitsIn;
33 bits = (bits << 16u) | (bits >> 16u);
34 bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
35 bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
36 bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
37 bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
38 return f32(bits) * 2.3283064365386963e-10;
39}
40
41fn basis(n: vec3f) -> mat3x3f {
42 let up = select(vec3f(1.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0), abs(n.z) < 0.999);
43 let tangent = normalize(cross(up, n));
44 return mat3x3f(tangent, cross(n, tangent), n);
45}
46
47fn sampleGgx(xi: vec2f, roughness: f32, n: vec3f) -> vec3f {
48 let a = max(roughness * roughness, 0.001);
49 let phi = 6.28318530718 * xi.x;
50 let cosTheta = sqrt((1.0 - xi.y) / max(1.0 + (a * a - 1.0) * xi.y, 0.0001));
51 let sinTheta = sqrt(max(1.0 - cosTheta * cosTheta, 0.0));
52 return normalize(basis(n) * vec3f(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta));
53}
54
55@fragment fn fs_main(in: VSOut) -> @location(0) vec4f {
56 let u = in.uv.x * 2.0 - 1.0;
57 let v = in.uv.y * 2.0 - 1.0;
58 let n = faceDirection(i32(params.data.x + 0.5), u, v);
59 let count = clamp(i32(params.data.w + 0.5), 8, 512);
60 var radiance = vec3f(0.0);
61 var weight = 0.0;
62 for (var i = 0; i < 512; i++) {
63 if (i >= count) { break; }
64 let xi = vec2f(f32(i) / f32(count), radicalInverse(u32(i)));
65 var l: vec3f;
66 if (params.data.z > 0.5) {
67 let phi = 6.28318530718 * xi.x;
68 let radius = sqrt(xi.y);
69 l = normalize(basis(n) * vec3f(cos(phi) * radius, sin(phi) * radius,
70 sqrt(max(1.0 - xi.y, 0.0))));
71 } else {
72 let h = sampleGgx(xi, params.data.y, n);
73 l = normalize(reflect(-n, h));
74 }
75 let noL = max(dot(n, l), 0.0);
76 if (noL > 0.0) {
77 let sampleWeight = select(noL, 1.0, params.data.z > 0.5);
78 radiance += textureSampleLevel(sourceCube, sourceSampler, l, 0.0).rgb * sampleWeight;
79 weight += sampleWeight;
80 }
81 }
82 return vec4f(radiance / max(weight, 0.0001), 1.0);
83}
84)wgsl";
85
86} // namespace eve::graphics::shaders
constexpr const char * kReflectionProbeFilterWgsl