@luma.gl/shaders 10.0.0-alpha.10 → 10.0.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1923 -60
- package/dist/dist.min.js +1499 -148
- package/dist/glsl.cjs.map +1 -1
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.cjs +40 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.d.ts +6 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.d.ts.map +1 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.js +15 -0
- package/dist/modules/lighting/clustered-light-grid/clustered-light-grid.js.map +1 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.cjs +348 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.d.ts +188 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.d.ts.map +1 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.js +307 -0
- package/dist/modules/lighting/contact-shadow/contact-shadow.js.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.cjs +93 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.d.ts +35 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.d.ts.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.js +71 -0
- package/dist/modules/lighting/lightmap/lightmap-filter.js.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap.cjs +89 -0
- package/dist/modules/lighting/lightmap/lightmap.d.ts +405 -0
- package/dist/modules/lighting/lightmap/lightmap.d.ts.map +1 -0
- package/dist/modules/lighting/lightmap/lightmap.js +67 -0
- package/dist/modules/lighting/lightmap/lightmap.js.map +1 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.cjs +87 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.d.ts +21 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.js +61 -0
- package/dist/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.js.map +1 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.cjs +87 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.d.ts +21 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.js +61 -0
- package/dist/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.js.map +1 -0
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.cjs +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.cjs +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +33 -11
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +3 -3
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.cjs +97 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.d.ts +15 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.js +69 -0
- package/dist/modules/lighting/pbr-shadow/pbr-shadow.js.map +1 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.cjs +114 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.d.ts +15 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.js +88 -0
- package/dist/modules/lighting/pbr-surface/pbr-surface.js.map +1 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.cjs +379 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.d.ts +41 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.d.ts.map +1 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.js +345 -0
- package/dist/modules/lighting/prefiltered-environment/prefiltered-environment.js.map +1 -0
- package/dist/modules/lighting/shadow/shadow-glsl.cjs +228 -0
- package/dist/modules/lighting/shadow/shadow-glsl.d.ts +3 -0
- package/dist/modules/lighting/shadow/shadow-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/shadow/shadow-glsl.js +204 -0
- package/dist/modules/lighting/shadow/shadow-glsl.js.map +1 -0
- package/dist/modules/lighting/shadow/shadow-types.cjs +15 -0
- package/dist/modules/lighting/shadow/shadow-types.d.ts +63 -0
- package/dist/modules/lighting/shadow/shadow-types.d.ts.map +1 -0
- package/dist/modules/lighting/shadow/shadow-types.js +5 -0
- package/dist/modules/lighting/shadow/shadow-types.js.map +1 -0
- package/dist/modules/lighting/shadow/shadow.cjs +458 -0
- package/dist/modules/lighting/shadow/shadow.d.ts +117 -0
- package/dist/modules/lighting/shadow/shadow.d.ts.map +1 -0
- package/dist/modules/lighting/shadow/shadow.js +450 -0
- package/dist/modules/lighting/shadow/shadow.js.map +1 -0
- package/dist/modules/lighting/unlit-material/unlit-material.cjs +60 -0
- package/dist/modules/lighting/unlit-material/unlit-material.d.ts +9 -0
- package/dist/modules/lighting/unlit-material/unlit-material.d.ts.map +1 -0
- package/dist/modules/lighting/unlit-material/unlit-material.js +40 -0
- package/dist/modules/lighting/unlit-material/unlit-material.js.map +1 -0
- package/dist/types/shader-type-decoder.cjs +12 -2
- package/dist/types/shader-type-decoder.d.ts +7 -7
- package/dist/types/shader-type-decoder.d.ts.map +1 -1
- package/dist/types/shader-type-decoder.js +13 -2
- package/dist/types/shader-type-decoder.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/wgsl.cjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +52 -0
- package/src/modules/lighting/clustered-light-grid/clustered-light-grid.ts +17 -0
- package/src/modules/lighting/contact-shadow/contact-shadow.ts +365 -0
- package/src/modules/lighting/lightmap/lightmap-filter.ts +73 -0
- package/src/modules/lighting/lightmap/lightmap.ts +76 -0
- package/src/modules/lighting/pbr-ambient-occlusion/pbr-ambient-occlusion.ts +78 -0
- package/src/modules/lighting/pbr-contact-shadow/pbr-contact-shadow.ts +78 -0
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +33 -11
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +33 -11
- package/src/modules/lighting/pbr-shadow/pbr-shadow.ts +85 -0
- package/src/modules/lighting/pbr-surface/pbr-surface.ts +103 -0
- package/src/modules/lighting/prefiltered-environment/prefiltered-environment.ts +370 -0
- package/src/modules/lighting/shadow/shadow-glsl.ts +204 -0
- package/src/modules/lighting/shadow/shadow-types.ts +68 -0
- package/src/modules/lighting/shadow/shadow.ts +536 -0
- package/src/modules/lighting/unlit-material/unlit-material.ts +44 -0
- package/src/types/shader-type-decoder.ts +22 -9
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var prefiltered_environment_exports = {};
|
|
19
|
+
__export(prefiltered_environment_exports, {
|
|
20
|
+
PBR_ENVIRONMENT_FRAGMENT_GLSL: () => PBR_ENVIRONMENT_FRAGMENT_GLSL,
|
|
21
|
+
PBR_ENVIRONMENT_FRAGMENT_WGSL: () => PBR_ENVIRONMENT_FRAGMENT_WGSL,
|
|
22
|
+
pbrEnvironmentFilter: () => pbrEnvironmentFilter
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(prefiltered_environment_exports);
|
|
25
|
+
const GLSL_UNIFORMS = (
|
|
26
|
+
/* glsl */
|
|
27
|
+
`layout(std140) uniform pbrEnvironmentFilterUniforms {
|
|
28
|
+
int face;
|
|
29
|
+
float roughness;
|
|
30
|
+
int mode;
|
|
31
|
+
int sampleCount;
|
|
32
|
+
int sourceEncoding;
|
|
33
|
+
} pbrEnvironmentFilter;
|
|
34
|
+
|
|
35
|
+
uniform sampler2D pbrEnvironmentSource;
|
|
36
|
+
`
|
|
37
|
+
);
|
|
38
|
+
const WGSL_UNIFORMS = (
|
|
39
|
+
/* wgsl */
|
|
40
|
+
`struct PBREnvironmentFilterUniforms {
|
|
41
|
+
face: i32,
|
|
42
|
+
roughness: f32,
|
|
43
|
+
mode: i32,
|
|
44
|
+
sampleCount: i32,
|
|
45
|
+
sourceEncoding: i32,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
@group(0) @binding(auto) var<uniform> pbrEnvironmentFilter: PBREnvironmentFilterUniforms;
|
|
49
|
+
@group(0) @binding(auto) var pbrEnvironmentSource: texture_2d<f32>;
|
|
50
|
+
@group(0) @binding(auto) var pbrEnvironmentSourceSampler: sampler;
|
|
51
|
+
`
|
|
52
|
+
);
|
|
53
|
+
const pbrEnvironmentFilter = {
|
|
54
|
+
name: "pbrEnvironmentFilter",
|
|
55
|
+
bindingLayout: [
|
|
56
|
+
{ name: "pbrEnvironmentFilter", group: 0 },
|
|
57
|
+
{ name: "pbrEnvironmentSource", group: 0 }
|
|
58
|
+
],
|
|
59
|
+
fs: GLSL_UNIFORMS,
|
|
60
|
+
source: WGSL_UNIFORMS,
|
|
61
|
+
getUniforms: (properties) => properties,
|
|
62
|
+
uniformTypes: {
|
|
63
|
+
face: "i32",
|
|
64
|
+
roughness: "f32",
|
|
65
|
+
mode: "i32",
|
|
66
|
+
sampleCount: "i32",
|
|
67
|
+
sourceEncoding: "i32"
|
|
68
|
+
},
|
|
69
|
+
defaultUniforms: {
|
|
70
|
+
face: 0,
|
|
71
|
+
roughness: 0,
|
|
72
|
+
mode: 0,
|
|
73
|
+
sampleCount: 64,
|
|
74
|
+
sourceEncoding: 0
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const PBR_ENVIRONMENT_FRAGMENT_GLSL = (
|
|
78
|
+
/* glsl */
|
|
79
|
+
`#version 300 es
|
|
80
|
+
precision highp float;
|
|
81
|
+
precision highp int;
|
|
82
|
+
|
|
83
|
+
in vec2 uv;
|
|
84
|
+
out vec4 fragmentColor;
|
|
85
|
+
|
|
86
|
+
const float ENVIRONMENT_PI = 3.141592653589793;
|
|
87
|
+
|
|
88
|
+
vec2 getEnvironmentHammersley(uint index, uint sampleCount)
|
|
89
|
+
{
|
|
90
|
+
uint reversedBits = (index << 16u) | (index >> 16u);
|
|
91
|
+
reversedBits = ((reversedBits & 0x55555555u) << 1u) |
|
|
92
|
+
((reversedBits & 0xAAAAAAAAu) >> 1u);
|
|
93
|
+
reversedBits = ((reversedBits & 0x33333333u) << 2u) |
|
|
94
|
+
((reversedBits & 0xCCCCCCCCu) >> 2u);
|
|
95
|
+
reversedBits = ((reversedBits & 0x0F0F0F0Fu) << 4u) |
|
|
96
|
+
((reversedBits & 0xF0F0F0F0u) >> 4u);
|
|
97
|
+
reversedBits = ((reversedBits & 0x00FF00FFu) << 8u) |
|
|
98
|
+
((reversedBits & 0xFF00FF00u) >> 8u);
|
|
99
|
+
return vec2(
|
|
100
|
+
float(index) / float(sampleCount),
|
|
101
|
+
float(reversedBits) * 2.3283064365386963e-10
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
vec3 getEnvironmentFaceDirection(int face, vec2 textureCoordinate)
|
|
106
|
+
{
|
|
107
|
+
vec2 coordinate = textureCoordinate * 2.0 - 1.0;
|
|
108
|
+
if (face == 0) return normalize(vec3(1.0, -coordinate.y, -coordinate.x));
|
|
109
|
+
if (face == 1) return normalize(vec3(-1.0, -coordinate.y, coordinate.x));
|
|
110
|
+
if (face == 2) return normalize(vec3(coordinate.x, 1.0, coordinate.y));
|
|
111
|
+
if (face == 3) return normalize(vec3(coordinate.x, -1.0, -coordinate.y));
|
|
112
|
+
if (face == 4) return normalize(vec3(coordinate.x, -coordinate.y, 1.0));
|
|
113
|
+
return normalize(vec3(-coordinate.x, -coordinate.y, -1.0));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
mat3 getEnvironmentTangentBasis(vec3 normal)
|
|
117
|
+
{
|
|
118
|
+
vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
|
119
|
+
vec3 tangent = normalize(cross(up, normal));
|
|
120
|
+
return mat3(tangent, cross(normal, tangent), normal);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
vec3 sampleEnvironmentDirection(vec3 direction)
|
|
124
|
+
{
|
|
125
|
+
vec3 normalizedDirection = normalize(direction);
|
|
126
|
+
vec2 textureCoordinate = vec2(
|
|
127
|
+
atan(normalizedDirection.z, normalizedDirection.x) / (2.0 * ENVIRONMENT_PI) + 0.5,
|
|
128
|
+
acos(clamp(normalizedDirection.y, -1.0, 1.0)) / ENVIRONMENT_PI
|
|
129
|
+
);
|
|
130
|
+
vec3 color = texture(pbrEnvironmentSource, textureCoordinate).rgb;
|
|
131
|
+
if (pbrEnvironmentFilter.sourceEncoding == 1) {
|
|
132
|
+
vec3 lower = color / 12.92;
|
|
133
|
+
vec3 upper = pow((color + 0.055) / 1.055, vec3(2.4));
|
|
134
|
+
color = mix(lower, upper, step(vec3(0.04045), color));
|
|
135
|
+
}
|
|
136
|
+
return color;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
vec3 importanceSampleEnvironment(vec2 sequence, vec3 normal, float roughness)
|
|
140
|
+
{
|
|
141
|
+
float alpha = max(roughness * roughness, 0.0001);
|
|
142
|
+
float azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
|
|
143
|
+
float cosine = sqrt(
|
|
144
|
+
(1.0 - sequence.y) / max(1.0 + (alpha * alpha - 1.0) * sequence.y, 0.0001)
|
|
145
|
+
);
|
|
146
|
+
float sine = sqrt(max(1.0 - cosine * cosine, 0.0));
|
|
147
|
+
vec3 halfVector = vec3(cos(azimuth) * sine, sin(azimuth) * sine, cosine);
|
|
148
|
+
return normalize(getEnvironmentTangentBasis(normal) * halfVector);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
float getEnvironmentGeometry(float normalDotDirection, float roughness)
|
|
152
|
+
{
|
|
153
|
+
float alpha = roughness * roughness;
|
|
154
|
+
float factor = alpha * 0.5;
|
|
155
|
+
return normalDotDirection / max(normalDotDirection * (1.0 - factor) + factor, 0.0001);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
vec2 integrateEnvironmentBRDF(vec2 textureCoordinate, int sampleCount)
|
|
159
|
+
{
|
|
160
|
+
float normalDotView = max(textureCoordinate.x, 0.001);
|
|
161
|
+
float roughness = 1.0 - textureCoordinate.y;
|
|
162
|
+
vec3 viewDirection = vec3(sqrt(max(1.0 - normalDotView * normalDotView, 0.0)), 0.0, normalDotView);
|
|
163
|
+
vec2 integration = vec2(0.0);
|
|
164
|
+
|
|
165
|
+
for (int sampleIndex = 0; sampleIndex < 1024; sampleIndex++) {
|
|
166
|
+
if (sampleIndex >= sampleCount) break;
|
|
167
|
+
vec3 halfVector = importanceSampleEnvironment(
|
|
168
|
+
getEnvironmentHammersley(uint(sampleIndex), uint(sampleCount)),
|
|
169
|
+
vec3(0.0, 0.0, 1.0),
|
|
170
|
+
roughness
|
|
171
|
+
);
|
|
172
|
+
vec3 lightDirection = normalize(2.0 * dot(viewDirection, halfVector) * halfVector - viewDirection);
|
|
173
|
+
float normalDotLight = max(lightDirection.z, 0.0);
|
|
174
|
+
float normalDotHalf = max(halfVector.z, 0.0);
|
|
175
|
+
float viewDotHalf = max(dot(viewDirection, halfVector), 0.0);
|
|
176
|
+
if (normalDotLight > 0.0) {
|
|
177
|
+
float visibility = getEnvironmentGeometry(normalDotView, roughness) *
|
|
178
|
+
getEnvironmentGeometry(normalDotLight, roughness) * viewDotHalf /
|
|
179
|
+
max(normalDotHalf * normalDotView, 0.0001);
|
|
180
|
+
float fresnel = pow(1.0 - viewDotHalf, 5.0);
|
|
181
|
+
integration += vec2(1.0 - fresnel, fresnel) * visibility;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return integration / float(sampleCount);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
vec3 integrateEnvironmentDirection(vec3 normal, int sampleCount)
|
|
188
|
+
{
|
|
189
|
+
vec3 accumulatedColor = vec3(0.0);
|
|
190
|
+
float accumulatedWeight = 0.0;
|
|
191
|
+
|
|
192
|
+
for (int sampleIndex = 0; sampleIndex < 1024; sampleIndex++) {
|
|
193
|
+
if (sampleIndex >= sampleCount) break;
|
|
194
|
+
vec2 sequence = getEnvironmentHammersley(uint(sampleIndex), uint(sampleCount));
|
|
195
|
+
vec3 direction;
|
|
196
|
+
float sampleWeight;
|
|
197
|
+
|
|
198
|
+
if (pbrEnvironmentFilter.mode == 1) {
|
|
199
|
+
float azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
|
|
200
|
+
float cosine = sqrt(1.0 - sequence.y);
|
|
201
|
+
float sine = sqrt(sequence.y);
|
|
202
|
+
direction = normalize(
|
|
203
|
+
getEnvironmentTangentBasis(normal) *
|
|
204
|
+
vec3(cos(azimuth) * sine, sin(azimuth) * sine, cosine)
|
|
205
|
+
);
|
|
206
|
+
sampleWeight = 1.0;
|
|
207
|
+
} else {
|
|
208
|
+
vec3 halfVector = importanceSampleEnvironment(sequence, normal, pbrEnvironmentFilter.roughness);
|
|
209
|
+
direction = normalize(2.0 * dot(normal, halfVector) * halfVector - normal);
|
|
210
|
+
sampleWeight = max(dot(normal, direction), 0.0);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
accumulatedColor += sampleEnvironmentDirection(direction) * sampleWeight;
|
|
214
|
+
accumulatedWeight += sampleWeight;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return accumulatedColor / max(accumulatedWeight, 0.0001);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
void main(void)
|
|
221
|
+
{
|
|
222
|
+
int sampleCount = max(pbrEnvironmentFilter.sampleCount, 1);
|
|
223
|
+
if (pbrEnvironmentFilter.mode == 2) {
|
|
224
|
+
fragmentColor = vec4(integrateEnvironmentBRDF(uv, sampleCount), 0.0, 1.0);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
vec3 direction = getEnvironmentFaceDirection(pbrEnvironmentFilter.face, uv);
|
|
229
|
+
fragmentColor = vec4(integrateEnvironmentDirection(direction, sampleCount), 1.0);
|
|
230
|
+
}
|
|
231
|
+
`
|
|
232
|
+
);
|
|
233
|
+
const PBR_ENVIRONMENT_FRAGMENT_WGSL = (
|
|
234
|
+
/* wgsl */
|
|
235
|
+
`const ENVIRONMENT_PI: f32 = 3.141592653589793;
|
|
236
|
+
|
|
237
|
+
fn getEnvironmentHammersley(index: u32, sampleCount: u32) -> vec2f {
|
|
238
|
+
return vec2f(f32(index) / f32(sampleCount), f32(reverseBits(index)) * 2.3283064365386963e-10);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
fn getEnvironmentFaceDirection(face: i32, textureCoordinate: vec2f) -> vec3f {
|
|
242
|
+
let coordinate = textureCoordinate * 2.0 - 1.0;
|
|
243
|
+
if (face == 0) { return normalize(vec3f(1.0, -coordinate.y, -coordinate.x)); }
|
|
244
|
+
if (face == 1) { return normalize(vec3f(-1.0, -coordinate.y, coordinate.x)); }
|
|
245
|
+
if (face == 2) { return normalize(vec3f(coordinate.x, 1.0, coordinate.y)); }
|
|
246
|
+
if (face == 3) { return normalize(vec3f(coordinate.x, -1.0, -coordinate.y)); }
|
|
247
|
+
if (face == 4) { return normalize(vec3f(coordinate.x, -coordinate.y, 1.0)); }
|
|
248
|
+
return normalize(vec3f(-coordinate.x, -coordinate.y, -1.0));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
fn getEnvironmentTangentBasis(normal: vec3f) -> mat3x3f {
|
|
252
|
+
var up = vec3f(1.0, 0.0, 0.0);
|
|
253
|
+
if (abs(normal.z) < 0.999) {
|
|
254
|
+
up = vec3f(0.0, 0.0, 1.0);
|
|
255
|
+
}
|
|
256
|
+
let tangent = normalize(cross(up, normal));
|
|
257
|
+
return mat3x3f(tangent, cross(normal, tangent), normal);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
fn sampleEnvironmentDirection(direction: vec3f) -> vec3f {
|
|
261
|
+
let normalizedDirection = normalize(direction);
|
|
262
|
+
let textureCoordinate = vec2f(
|
|
263
|
+
atan2(normalizedDirection.z, normalizedDirection.x) / (2.0 * ENVIRONMENT_PI) + 0.5,
|
|
264
|
+
acos(clamp(normalizedDirection.y, -1.0, 1.0)) / ENVIRONMENT_PI
|
|
265
|
+
);
|
|
266
|
+
var color = textureSampleLevel(
|
|
267
|
+
pbrEnvironmentSource,
|
|
268
|
+
pbrEnvironmentSourceSampler,
|
|
269
|
+
textureCoordinate,
|
|
270
|
+
0.0
|
|
271
|
+
).rgb;
|
|
272
|
+
if (pbrEnvironmentFilter.sourceEncoding == 1) {
|
|
273
|
+
let lower = color / 12.92;
|
|
274
|
+
let upper = pow((color + 0.055) / 1.055, vec3f(2.4));
|
|
275
|
+
color = mix(lower, upper, step(vec3f(0.04045), color));
|
|
276
|
+
}
|
|
277
|
+
return color;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
fn importanceSampleEnvironment(sequence: vec2f, normal: vec3f, roughness: f32) -> vec3f {
|
|
281
|
+
let alpha = max(roughness * roughness, 0.0001);
|
|
282
|
+
let azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
|
|
283
|
+
let cosine = sqrt(
|
|
284
|
+
(1.0 - sequence.y) / max(1.0 + (alpha * alpha - 1.0) * sequence.y, 0.0001)
|
|
285
|
+
);
|
|
286
|
+
let sine = sqrt(max(1.0 - cosine * cosine, 0.0));
|
|
287
|
+
let halfVector = vec3f(cos(azimuth) * sine, sin(azimuth) * sine, cosine);
|
|
288
|
+
return normalize(getEnvironmentTangentBasis(normal) * halfVector);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
fn getEnvironmentGeometry(normalDotDirection: f32, roughness: f32) -> f32 {
|
|
292
|
+
let alpha = roughness * roughness;
|
|
293
|
+
let factor = alpha * 0.5;
|
|
294
|
+
return normalDotDirection / max(normalDotDirection * (1.0 - factor) + factor, 0.0001);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
fn integrateEnvironmentBRDF(textureCoordinate: vec2f, sampleCount: u32) -> vec2f {
|
|
298
|
+
let normalDotView = max(textureCoordinate.x, 0.001);
|
|
299
|
+
let roughness = 1.0 - textureCoordinate.y;
|
|
300
|
+
let viewDirection = vec3f(
|
|
301
|
+
sqrt(max(1.0 - normalDotView * normalDotView, 0.0)),
|
|
302
|
+
0.0,
|
|
303
|
+
normalDotView
|
|
304
|
+
);
|
|
305
|
+
var integration = vec2f(0.0);
|
|
306
|
+
|
|
307
|
+
for (var sampleIndex = 0u; sampleIndex < sampleCount; sampleIndex++) {
|
|
308
|
+
let halfVector = importanceSampleEnvironment(
|
|
309
|
+
getEnvironmentHammersley(sampleIndex, sampleCount),
|
|
310
|
+
vec3f(0.0, 0.0, 1.0),
|
|
311
|
+
roughness
|
|
312
|
+
);
|
|
313
|
+
let lightDirection = normalize(
|
|
314
|
+
2.0 * dot(viewDirection, halfVector) * halfVector - viewDirection
|
|
315
|
+
);
|
|
316
|
+
let normalDotLight = max(lightDirection.z, 0.0);
|
|
317
|
+
let normalDotHalf = max(halfVector.z, 0.0);
|
|
318
|
+
let viewDotHalf = max(dot(viewDirection, halfVector), 0.0);
|
|
319
|
+
if (normalDotLight > 0.0) {
|
|
320
|
+
let visibility = getEnvironmentGeometry(normalDotView, roughness) *
|
|
321
|
+
getEnvironmentGeometry(normalDotLight, roughness) * viewDotHalf /
|
|
322
|
+
max(normalDotHalf * normalDotView, 0.0001);
|
|
323
|
+
let fresnel = pow(1.0 - viewDotHalf, 5.0);
|
|
324
|
+
integration += vec2f(1.0 - fresnel, fresnel) * visibility;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return integration / f32(sampleCount);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
fn integrateEnvironmentDirection(normal: vec3f, sampleCount: u32) -> vec3f {
|
|
331
|
+
var accumulatedColor = vec3f(0.0);
|
|
332
|
+
var accumulatedWeight = 0.0;
|
|
333
|
+
|
|
334
|
+
for (var sampleIndex = 0u; sampleIndex < sampleCount; sampleIndex++) {
|
|
335
|
+
let sequence = getEnvironmentHammersley(sampleIndex, sampleCount);
|
|
336
|
+
var direction: vec3f;
|
|
337
|
+
var sampleWeight: f32;
|
|
338
|
+
|
|
339
|
+
if (pbrEnvironmentFilter.mode == 1) {
|
|
340
|
+
let azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;
|
|
341
|
+
let cosine = sqrt(1.0 - sequence.y);
|
|
342
|
+
let sine = sqrt(sequence.y);
|
|
343
|
+
direction = normalize(
|
|
344
|
+
getEnvironmentTangentBasis(normal) *
|
|
345
|
+
vec3f(cos(azimuth) * sine, sin(azimuth) * sine, cosine)
|
|
346
|
+
);
|
|
347
|
+
sampleWeight = 1.0;
|
|
348
|
+
} else {
|
|
349
|
+
let halfVector = importanceSampleEnvironment(sequence, normal, pbrEnvironmentFilter.roughness);
|
|
350
|
+
direction = normalize(2.0 * dot(normal, halfVector) * halfVector - normal);
|
|
351
|
+
sampleWeight = max(dot(normal, direction), 0.0);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
accumulatedColor += sampleEnvironmentDirection(direction) * sampleWeight;
|
|
355
|
+
accumulatedWeight += sampleWeight;
|
|
356
|
+
}
|
|
357
|
+
return accumulatedColor / max(accumulatedWeight, 0.0001);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
@fragment
|
|
361
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
362
|
+
// ClipSpace UVs increase upward; WebGPU texture rows increase downward.
|
|
363
|
+
let textureCoordinate = vec2f(inputs.uv.x, 1.0 - inputs.uv.y);
|
|
364
|
+
let sampleCount = u32(max(pbrEnvironmentFilter.sampleCount, 1));
|
|
365
|
+
if (pbrEnvironmentFilter.mode == 2) {
|
|
366
|
+
return vec4f(integrateEnvironmentBRDF(textureCoordinate, sampleCount), 0.0, 1.0);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
let direction = getEnvironmentFaceDirection(pbrEnvironmentFilter.face, textureCoordinate);
|
|
370
|
+
return vec4f(integrateEnvironmentDirection(direction, sampleCount), 1.0);
|
|
371
|
+
}
|
|
372
|
+
`
|
|
373
|
+
);
|
|
374
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
375
|
+
0 && (module.exports = {
|
|
376
|
+
PBR_ENVIRONMENT_FRAGMENT_GLSL,
|
|
377
|
+
PBR_ENVIRONMENT_FRAGMENT_WGSL,
|
|
378
|
+
pbrEnvironmentFilter
|
|
379
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type PBREnvironmentFilterUniforms = {
|
|
2
|
+
face: number;
|
|
3
|
+
roughness: number;
|
|
4
|
+
mode: number;
|
|
5
|
+
sampleCount: number;
|
|
6
|
+
sourceEncoding: number;
|
|
7
|
+
};
|
|
8
|
+
export type PBREnvironmentFilterBindings<TextureT = unknown> = {
|
|
9
|
+
pbrEnvironmentSource: TextureT;
|
|
10
|
+
};
|
|
11
|
+
export type PBREnvironmentFilterProps<TextureT = unknown> = PBREnvironmentFilterUniforms & PBREnvironmentFilterBindings<TextureT>;
|
|
12
|
+
export declare const pbrEnvironmentFilter: {
|
|
13
|
+
readonly name: "pbrEnvironmentFilter";
|
|
14
|
+
readonly bindingLayout: readonly [{
|
|
15
|
+
readonly name: "pbrEnvironmentFilter";
|
|
16
|
+
readonly group: 0;
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "pbrEnvironmentSource";
|
|
19
|
+
readonly group: 0;
|
|
20
|
+
}];
|
|
21
|
+
readonly fs: "layout(std140) uniform pbrEnvironmentFilterUniforms {\n int face;\n float roughness;\n int mode;\n int sampleCount;\n int sourceEncoding;\n} pbrEnvironmentFilter;\n\nuniform sampler2D pbrEnvironmentSource;\n";
|
|
22
|
+
readonly source: "struct PBREnvironmentFilterUniforms {\n face: i32,\n roughness: f32,\n mode: i32,\n sampleCount: i32,\n sourceEncoding: i32,\n};\n\n@group(0) @binding(auto) var<uniform> pbrEnvironmentFilter: PBREnvironmentFilterUniforms;\n@group(0) @binding(auto) var pbrEnvironmentSource: texture_2d<f32>;\n@group(0) @binding(auto) var pbrEnvironmentSourceSampler: sampler;\n";
|
|
23
|
+
readonly getUniforms: (properties: Partial<PBREnvironmentFilterProps>) => Partial<PBREnvironmentFilterProps<unknown>>;
|
|
24
|
+
readonly uniformTypes: {
|
|
25
|
+
readonly face: "i32";
|
|
26
|
+
readonly roughness: "f32";
|
|
27
|
+
readonly mode: "i32";
|
|
28
|
+
readonly sampleCount: "i32";
|
|
29
|
+
readonly sourceEncoding: "i32";
|
|
30
|
+
};
|
|
31
|
+
readonly defaultUniforms: {
|
|
32
|
+
readonly face: 0;
|
|
33
|
+
readonly roughness: 0;
|
|
34
|
+
readonly mode: 0;
|
|
35
|
+
readonly sampleCount: 64;
|
|
36
|
+
readonly sourceEncoding: 0;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare const PBR_ENVIRONMENT_FRAGMENT_GLSL = "#version 300 es\nprecision highp float;\nprecision highp int;\n\nin vec2 uv;\nout vec4 fragmentColor;\n\nconst float ENVIRONMENT_PI = 3.141592653589793;\n\nvec2 getEnvironmentHammersley(uint index, uint sampleCount)\n{\n uint reversedBits = (index << 16u) | (index >> 16u);\n reversedBits = ((reversedBits & 0x55555555u) << 1u) |\n ((reversedBits & 0xAAAAAAAAu) >> 1u);\n reversedBits = ((reversedBits & 0x33333333u) << 2u) |\n ((reversedBits & 0xCCCCCCCCu) >> 2u);\n reversedBits = ((reversedBits & 0x0F0F0F0Fu) << 4u) |\n ((reversedBits & 0xF0F0F0F0u) >> 4u);\n reversedBits = ((reversedBits & 0x00FF00FFu) << 8u) |\n ((reversedBits & 0xFF00FF00u) >> 8u);\n return vec2(\n float(index) / float(sampleCount),\n float(reversedBits) * 2.3283064365386963e-10\n );\n}\n\nvec3 getEnvironmentFaceDirection(int face, vec2 textureCoordinate)\n{\n vec2 coordinate = textureCoordinate * 2.0 - 1.0;\n if (face == 0) return normalize(vec3(1.0, -coordinate.y, -coordinate.x));\n if (face == 1) return normalize(vec3(-1.0, -coordinate.y, coordinate.x));\n if (face == 2) return normalize(vec3(coordinate.x, 1.0, coordinate.y));\n if (face == 3) return normalize(vec3(coordinate.x, -1.0, -coordinate.y));\n if (face == 4) return normalize(vec3(coordinate.x, -coordinate.y, 1.0));\n return normalize(vec3(-coordinate.x, -coordinate.y, -1.0));\n}\n\nmat3 getEnvironmentTangentBasis(vec3 normal)\n{\n vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n vec3 tangent = normalize(cross(up, normal));\n return mat3(tangent, cross(normal, tangent), normal);\n}\n\nvec3 sampleEnvironmentDirection(vec3 direction)\n{\n vec3 normalizedDirection = normalize(direction);\n vec2 textureCoordinate = vec2(\n atan(normalizedDirection.z, normalizedDirection.x) / (2.0 * ENVIRONMENT_PI) + 0.5,\n acos(clamp(normalizedDirection.y, -1.0, 1.0)) / ENVIRONMENT_PI\n );\n vec3 color = texture(pbrEnvironmentSource, textureCoordinate).rgb;\n if (pbrEnvironmentFilter.sourceEncoding == 1) {\n vec3 lower = color / 12.92;\n vec3 upper = pow((color + 0.055) / 1.055, vec3(2.4));\n color = mix(lower, upper, step(vec3(0.04045), color));\n }\n return color;\n}\n\nvec3 importanceSampleEnvironment(vec2 sequence, vec3 normal, float roughness)\n{\n float alpha = max(roughness * roughness, 0.0001);\n float azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;\n float cosine = sqrt(\n (1.0 - sequence.y) / max(1.0 + (alpha * alpha - 1.0) * sequence.y, 0.0001)\n );\n float sine = sqrt(max(1.0 - cosine * cosine, 0.0));\n vec3 halfVector = vec3(cos(azimuth) * sine, sin(azimuth) * sine, cosine);\n return normalize(getEnvironmentTangentBasis(normal) * halfVector);\n}\n\nfloat getEnvironmentGeometry(float normalDotDirection, float roughness)\n{\n float alpha = roughness * roughness;\n float factor = alpha * 0.5;\n return normalDotDirection / max(normalDotDirection * (1.0 - factor) + factor, 0.0001);\n}\n\nvec2 integrateEnvironmentBRDF(vec2 textureCoordinate, int sampleCount)\n{\n float normalDotView = max(textureCoordinate.x, 0.001);\n float roughness = 1.0 - textureCoordinate.y;\n vec3 viewDirection = vec3(sqrt(max(1.0 - normalDotView * normalDotView, 0.0)), 0.0, normalDotView);\n vec2 integration = vec2(0.0);\n\n for (int sampleIndex = 0; sampleIndex < 1024; sampleIndex++) {\n if (sampleIndex >= sampleCount) break;\n vec3 halfVector = importanceSampleEnvironment(\n getEnvironmentHammersley(uint(sampleIndex), uint(sampleCount)),\n vec3(0.0, 0.0, 1.0),\n roughness\n );\n vec3 lightDirection = normalize(2.0 * dot(viewDirection, halfVector) * halfVector - viewDirection);\n float normalDotLight = max(lightDirection.z, 0.0);\n float normalDotHalf = max(halfVector.z, 0.0);\n float viewDotHalf = max(dot(viewDirection, halfVector), 0.0);\n if (normalDotLight > 0.0) {\n float visibility = getEnvironmentGeometry(normalDotView, roughness) *\n getEnvironmentGeometry(normalDotLight, roughness) * viewDotHalf /\n max(normalDotHalf * normalDotView, 0.0001);\n float fresnel = pow(1.0 - viewDotHalf, 5.0);\n integration += vec2(1.0 - fresnel, fresnel) * visibility;\n }\n }\n return integration / float(sampleCount);\n}\n\nvec3 integrateEnvironmentDirection(vec3 normal, int sampleCount)\n{\n vec3 accumulatedColor = vec3(0.0);\n float accumulatedWeight = 0.0;\n\n for (int sampleIndex = 0; sampleIndex < 1024; sampleIndex++) {\n if (sampleIndex >= sampleCount) break;\n vec2 sequence = getEnvironmentHammersley(uint(sampleIndex), uint(sampleCount));\n vec3 direction;\n float sampleWeight;\n\n if (pbrEnvironmentFilter.mode == 1) {\n float azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;\n float cosine = sqrt(1.0 - sequence.y);\n float sine = sqrt(sequence.y);\n direction = normalize(\n getEnvironmentTangentBasis(normal) *\n vec3(cos(azimuth) * sine, sin(azimuth) * sine, cosine)\n );\n sampleWeight = 1.0;\n } else {\n vec3 halfVector = importanceSampleEnvironment(sequence, normal, pbrEnvironmentFilter.roughness);\n direction = normalize(2.0 * dot(normal, halfVector) * halfVector - normal);\n sampleWeight = max(dot(normal, direction), 0.0);\n }\n\n accumulatedColor += sampleEnvironmentDirection(direction) * sampleWeight;\n accumulatedWeight += sampleWeight;\n }\n\n return accumulatedColor / max(accumulatedWeight, 0.0001);\n}\n\nvoid main(void)\n{\n int sampleCount = max(pbrEnvironmentFilter.sampleCount, 1);\n if (pbrEnvironmentFilter.mode == 2) {\n fragmentColor = vec4(integrateEnvironmentBRDF(uv, sampleCount), 0.0, 1.0);\n return;\n }\n\n vec3 direction = getEnvironmentFaceDirection(pbrEnvironmentFilter.face, uv);\n fragmentColor = vec4(integrateEnvironmentDirection(direction, sampleCount), 1.0);\n}\n";
|
|
40
|
+
export declare const PBR_ENVIRONMENT_FRAGMENT_WGSL = "const ENVIRONMENT_PI: f32 = 3.141592653589793;\n\nfn getEnvironmentHammersley(index: u32, sampleCount: u32) -> vec2f {\n return vec2f(f32(index) / f32(sampleCount), f32(reverseBits(index)) * 2.3283064365386963e-10);\n}\n\nfn getEnvironmentFaceDirection(face: i32, textureCoordinate: vec2f) -> vec3f {\n let coordinate = textureCoordinate * 2.0 - 1.0;\n if (face == 0) { return normalize(vec3f(1.0, -coordinate.y, -coordinate.x)); }\n if (face == 1) { return normalize(vec3f(-1.0, -coordinate.y, coordinate.x)); }\n if (face == 2) { return normalize(vec3f(coordinate.x, 1.0, coordinate.y)); }\n if (face == 3) { return normalize(vec3f(coordinate.x, -1.0, -coordinate.y)); }\n if (face == 4) { return normalize(vec3f(coordinate.x, -coordinate.y, 1.0)); }\n return normalize(vec3f(-coordinate.x, -coordinate.y, -1.0));\n}\n\nfn getEnvironmentTangentBasis(normal: vec3f) -> mat3x3f {\n var up = vec3f(1.0, 0.0, 0.0);\n if (abs(normal.z) < 0.999) {\n up = vec3f(0.0, 0.0, 1.0);\n }\n let tangent = normalize(cross(up, normal));\n return mat3x3f(tangent, cross(normal, tangent), normal);\n}\n\nfn sampleEnvironmentDirection(direction: vec3f) -> vec3f {\n let normalizedDirection = normalize(direction);\n let textureCoordinate = vec2f(\n atan2(normalizedDirection.z, normalizedDirection.x) / (2.0 * ENVIRONMENT_PI) + 0.5,\n acos(clamp(normalizedDirection.y, -1.0, 1.0)) / ENVIRONMENT_PI\n );\n var color = textureSampleLevel(\n pbrEnvironmentSource,\n pbrEnvironmentSourceSampler,\n textureCoordinate,\n 0.0\n ).rgb;\n if (pbrEnvironmentFilter.sourceEncoding == 1) {\n let lower = color / 12.92;\n let upper = pow((color + 0.055) / 1.055, vec3f(2.4));\n color = mix(lower, upper, step(vec3f(0.04045), color));\n }\n return color;\n}\n\nfn importanceSampleEnvironment(sequence: vec2f, normal: vec3f, roughness: f32) -> vec3f {\n let alpha = max(roughness * roughness, 0.0001);\n let azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;\n let cosine = sqrt(\n (1.0 - sequence.y) / max(1.0 + (alpha * alpha - 1.0) * sequence.y, 0.0001)\n );\n let sine = sqrt(max(1.0 - cosine * cosine, 0.0));\n let halfVector = vec3f(cos(azimuth) * sine, sin(azimuth) * sine, cosine);\n return normalize(getEnvironmentTangentBasis(normal) * halfVector);\n}\n\nfn getEnvironmentGeometry(normalDotDirection: f32, roughness: f32) -> f32 {\n let alpha = roughness * roughness;\n let factor = alpha * 0.5;\n return normalDotDirection / max(normalDotDirection * (1.0 - factor) + factor, 0.0001);\n}\n\nfn integrateEnvironmentBRDF(textureCoordinate: vec2f, sampleCount: u32) -> vec2f {\n let normalDotView = max(textureCoordinate.x, 0.001);\n let roughness = 1.0 - textureCoordinate.y;\n let viewDirection = vec3f(\n sqrt(max(1.0 - normalDotView * normalDotView, 0.0)),\n 0.0,\n normalDotView\n );\n var integration = vec2f(0.0);\n\n for (var sampleIndex = 0u; sampleIndex < sampleCount; sampleIndex++) {\n let halfVector = importanceSampleEnvironment(\n getEnvironmentHammersley(sampleIndex, sampleCount),\n vec3f(0.0, 0.0, 1.0),\n roughness\n );\n let lightDirection = normalize(\n 2.0 * dot(viewDirection, halfVector) * halfVector - viewDirection\n );\n let normalDotLight = max(lightDirection.z, 0.0);\n let normalDotHalf = max(halfVector.z, 0.0);\n let viewDotHalf = max(dot(viewDirection, halfVector), 0.0);\n if (normalDotLight > 0.0) {\n let visibility = getEnvironmentGeometry(normalDotView, roughness) *\n getEnvironmentGeometry(normalDotLight, roughness) * viewDotHalf /\n max(normalDotHalf * normalDotView, 0.0001);\n let fresnel = pow(1.0 - viewDotHalf, 5.0);\n integration += vec2f(1.0 - fresnel, fresnel) * visibility;\n }\n }\n return integration / f32(sampleCount);\n}\n\nfn integrateEnvironmentDirection(normal: vec3f, sampleCount: u32) -> vec3f {\n var accumulatedColor = vec3f(0.0);\n var accumulatedWeight = 0.0;\n\n for (var sampleIndex = 0u; sampleIndex < sampleCount; sampleIndex++) {\n let sequence = getEnvironmentHammersley(sampleIndex, sampleCount);\n var direction: vec3f;\n var sampleWeight: f32;\n\n if (pbrEnvironmentFilter.mode == 1) {\n let azimuth = 2.0 * ENVIRONMENT_PI * sequence.x;\n let cosine = sqrt(1.0 - sequence.y);\n let sine = sqrt(sequence.y);\n direction = normalize(\n getEnvironmentTangentBasis(normal) *\n vec3f(cos(azimuth) * sine, sin(azimuth) * sine, cosine)\n );\n sampleWeight = 1.0;\n } else {\n let halfVector = importanceSampleEnvironment(sequence, normal, pbrEnvironmentFilter.roughness);\n direction = normalize(2.0 * dot(normal, halfVector) * halfVector - normal);\n sampleWeight = max(dot(normal, direction), 0.0);\n }\n\n accumulatedColor += sampleEnvironmentDirection(direction) * sampleWeight;\n accumulatedWeight += sampleWeight;\n }\n return accumulatedColor / max(accumulatedWeight, 0.0001);\n}\n\n@fragment\nfn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {\n // ClipSpace UVs increase upward; WebGPU texture rows increase downward.\n let textureCoordinate = vec2f(inputs.uv.x, 1.0 - inputs.uv.y);\n let sampleCount = u32(max(pbrEnvironmentFilter.sampleCount, 1));\n if (pbrEnvironmentFilter.mode == 2) {\n return vec4f(integrateEnvironmentBRDF(textureCoordinate, sampleCount), 0.0, 1.0);\n }\n\n let direction = getEnvironmentFaceDirection(pbrEnvironmentFilter.face, textureCoordinate);\n return vec4f(integrateEnvironmentDirection(direction, sampleCount), 1.0);\n}\n";
|
|
41
|
+
//# sourceMappingURL=prefiltered-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefiltered-environment.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/prefiltered-environment/prefiltered-environment.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,4BAA4B,CAAC,QAAQ,GAAG,OAAO,IAAI;IAC7D,oBAAoB,EAAE,QAAQ,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,yBAAyB,CAAC,QAAQ,GAAG,OAAO,IAAI,4BAA4B,GACtF,4BAA4B,CAAC,QAAQ,CAAC,CAAC;AA4BzC,eAAO,MAAM,oBAAoB;;;;;;;;;;;uCAQL,OAAO,CAAC,yBAAyB,CAAC;;;;;;;;;;;;;;;CAmB7D,CAAC;AAEF,eAAO,MAAM,6BAA6B,guLAyJzC,CAAC;AAEF,eAAO,MAAM,6BAA6B,m8KA0IzC,CAAC"}
|