@driftengine/core 4.8.6 → 4.8.7
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/CHANGELOG.json +71 -0
- package/README.md +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/render/anisotropicLobe.d.ts +10 -0
- package/dist/render/anisotropicLobe.js +19 -0
- package/dist/render/areaLights.d.ts +35 -0
- package/dist/render/areaLights.js +35 -0
- package/dist/render/backend/api.d.ts +33 -3
- package/dist/render/backend/webgl2/renderer.d.ts +50 -14
- package/dist/render/backend/webgl2/renderer.js +141 -30
- package/dist/render/backend/webgl2/sceneCaptureTarget.d.ts +29 -0
- package/dist/render/backend/webgl2/sceneCaptureTarget.js +96 -0
- package/dist/render/backend/webgpu/particlePass.js +2 -1
- package/dist/render/backend/webgpu/renderer.d.ts +35 -1
- package/dist/render/backend/webgpu/renderer.js +155 -16
- package/dist/render/backend/webgpu/sceneCaptureTarget.d.ts +24 -0
- package/dist/render/backend/webgpu/sceneCaptureTarget.js +59 -0
- package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.d.ts +1 -1
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +4 -1
- package/dist/render/backend/webgpu/surfaceTexturePass.js +34 -8
- package/dist/render/backend/webgpu/waterPass.d.ts +1 -1
- package/dist/render/clusteredLights.d.ts +23 -5
- package/dist/render/clusteredLights.js +35 -8
- package/dist/render/driftLight/bake.d.ts +2 -0
- package/dist/render/driftLight/bake.js +1 -1
- package/dist/render/driftLight/falloff.d.ts +4 -2
- package/dist/render/driftLight/falloff.js +8 -2
- package/dist/render/gi/bounceLights.d.ts +3 -2
- package/dist/render/gi/bounceLights.js +8 -3
- package/dist/render/instanceCull.js +5 -0
- package/dist/render/instances.d.ts +19 -5
- package/dist/render/instances.js +9 -3
- package/dist/render/lightBudget.d.ts +12 -1
- package/dist/render/lightBudget.js +23 -3
- package/dist/render/lightmap.d.ts +23 -9
- package/dist/render/lightmap.js +40 -18
- package/dist/render/particlePool.d.ts +21 -0
- package/dist/render/particlePool.js +7 -0
- package/dist/render/pointLightSelection.d.ts +13 -0
- package/dist/render/pointLightSelection.js +3 -1
- package/dist/render/renderQuality.d.ts +8 -7
- package/dist/render/rendererHarness.js +3 -0
- package/dist/render/rgb9e5.d.ts +22 -0
- package/dist/render/rgb9e5.js +47 -0
- package/dist/render/sceneCapture.d.ts +29 -0
- package/dist/render/sceneCapture.js +36 -0
- package/dist/render/screenSpaceReflection.d.ts +27 -1
- package/dist/render/screenSpaceReflection.js +9 -0
- package/dist/render/shaders/bolt.d.ts +1 -1
- package/dist/render/shaders/bolt.js +7 -1
- package/dist/render/shaders/depth.js +11 -0
- package/dist/render/shaders/flat/anisotropic.d.ts +1 -1
- package/dist/render/shaders/flat/anisotropic.js +37 -3
- package/dist/render/shaders/flat/areaLight.d.ts +1 -1
- package/dist/render/shaders/flat/areaLight.js +46 -0
- package/dist/render/shaders/flat/glassTint.d.ts +3 -2
- package/dist/render/shaders/flat/glassTint.js +3 -1
- package/dist/render/shaders/flat/index.d.ts +5 -0
- package/dist/render/shaders/flat/index.js +16 -2
- package/dist/render/shaders/flat/lobes.d.ts +6 -0
- package/dist/render/shaders/flat/lobes.js +49 -43
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +57 -22
- package/dist/render/shaders/flat/models.d.ts +5 -2
- package/dist/render/shaders/flat/models.js +100 -16
- package/dist/render/shaders/flat/preamble.js +10 -3
- package/dist/render/shaders/generated/bolt.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/bolt.wgsl.js +1 -1
- package/dist/render/shaders/generated/depth.wgsl.d.ts +4 -4
- package/dist/render/shaders/generated/depth.wgsl.js +4 -4
- package/dist/render/shaders/generated/flat.wgsl.d.ts +16 -0
- package/dist/render/shaders/generated/flat.wgsl.js +54 -38
- package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +11 -6
- package/dist/render/shaders/generated/ssrTrace.wgsl.js +11 -6
- package/dist/render/shaders/generated/water.wgsl.d.ts +23 -16
- package/dist/render/shaders/generated/water.wgsl.js +23 -16
- package/dist/render/shaders/gi/probeBake.wgsl.js +9 -5
- package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
- package/dist/render/shaders/recon/motion.wgsl.js +13 -2
- package/dist/render/shaders/ssrTrace.js +20 -1
- package/dist/render/shaders/water.d.ts +1 -1
- package/dist/render/shaders/water.js +12 -3
- package/dist/render/skinScatter.d.ts +3 -1
- package/dist/render/skinScatter.js +3 -1
- package/dist/render/ssrPass.js +1 -0
- package/dist/render/surfaceModel.d.ts +29 -8
- package/dist/render/surfaceModel.js +33 -9
- package/dist/render/surfaceTexture.d.ts +25 -1
- package/dist/render/surfaceTexture.js +27 -5
- package/package.json +6 -6
- package/src/index.ts +6 -2
- package/src/render/anisotropicLobe.ts +29 -0
- package/src/render/areaLights.ts +58 -0
- package/src/render/backend/api.ts +49 -2
- package/src/render/backend/webgl2/renderer.ts +192 -38
- package/src/render/backend/webgl2/sceneCaptureTarget.ts +130 -0
- package/src/render/backend/webgpu/particlePass.ts +2 -1
- package/src/render/backend/webgpu/renderer.ts +194 -19
- package/src/render/backend/webgpu/sceneCaptureTarget.ts +63 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +44 -14
- package/src/render/clusteredLights.ts +41 -8
- package/src/render/driftLight/bake.ts +3 -1
- package/src/render/driftLight/falloff.ts +13 -2
- package/src/render/gi/bounceLights.ts +12 -3
- package/src/render/instanceCull.ts +4 -0
- package/src/render/instances.ts +26 -6
- package/src/render/lightBudget.ts +40 -2
- package/src/render/lightmap.ts +64 -23
- package/src/render/particlePool.ts +23 -0
- package/src/render/pointLightSelection.ts +20 -1
- package/src/render/renderQuality.ts +8 -7
- package/src/render/rendererHarness.ts +3 -0
- package/src/render/rgb9e5.ts +52 -0
- package/src/render/sceneCapture.ts +56 -0
- package/src/render/screenSpaceReflection.ts +33 -1
- package/src/render/shaders/bolt.ts +7 -1
- package/src/render/shaders/depth.ts +11 -0
- package/src/render/shaders/flat/anisotropic.ts +37 -3
- package/src/render/shaders/flat/areaLight.ts +46 -0
- package/src/render/shaders/flat/glassTint.ts +9 -2
- package/src/render/shaders/flat/index.ts +21 -2
- package/src/render/shaders/flat/lobes.ts +50 -43
- package/src/render/shaders/flat/main.ts +57 -22
- package/src/render/shaders/flat/models.ts +100 -16
- package/src/render/shaders/flat/preamble.ts +10 -3
- package/src/render/shaders/generated/bolt.wgsl.ts +1 -1
- package/src/render/shaders/generated/depth.wgsl.ts +4 -4
- package/src/render/shaders/generated/flat.wgsl.ts +54 -38
- package/src/render/shaders/generated/ssrTrace.wgsl.ts +11 -6
- package/src/render/shaders/generated/water.wgsl.ts +23 -16
- package/src/render/shaders/gi/probeBake.wgsl.ts +9 -5
- package/src/render/shaders/recon/motion.wgsl.ts +13 -2
- package/src/render/shaders/ssrTrace.ts +20 -1
- package/src/render/shaders/water.ts +12 -3
- package/src/render/skinScatter.ts +3 -1
- package/src/render/ssrPass.ts +1 -0
- package/src/render/surfaceModel.ts +47 -10
- package/src/render/surfaceTexture.ts +69 -9
|
@@ -31,6 +31,7 @@ export function noLitSwitches() {
|
|
|
31
31
|
LIGHT_FIXTURES: false,
|
|
32
32
|
SURFACE_EFFECTS: false,
|
|
33
33
|
DRIFT_LIGHT: false,
|
|
34
|
+
PHYSICAL_SPECULAR: false,
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
@@ -44,7 +45,8 @@ export function noLitSwitches() {
|
|
|
44
45
|
* first uses them — a measured profile or a cookie, a material with an effects table, a DriftLight
|
|
45
46
|
* volume — and then on for good; see `PipelineCache.enable` and the WebGL2 renderer's rebuild.
|
|
46
47
|
* Measured on RADV against the lit shader with glass already out: 6,852 instructions and 120
|
|
47
|
-
* registers, 4,641 and 96 with all four out.
|
|
48
|
+
* registers, 4,641 and 96 with all four out. `PHYSICAL_SPECULAR` is a sixth, declared with the
|
|
49
|
+
* models so that theirs keep their ids (`modelsGlsl`).
|
|
48
50
|
*/
|
|
49
51
|
export function litSwitchesGlsl(switches) {
|
|
50
52
|
return /* glsl */ `
|
|
@@ -104,6 +104,11 @@ export interface FlatShaderOptions {
|
|
|
104
104
|
readonly surfaceEffects?: boolean;
|
|
105
105
|
/** Whether it reads a DriftLight volume. True when absent. See `litSwitchesGlsl`. */
|
|
106
106
|
readonly driftLight?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Whether it carries GGX's own highlight for a material that asks (`physicalSpecular`). True
|
|
109
|
+
* when absent. See `modelsGlsl`.
|
|
110
|
+
*/
|
|
111
|
+
readonly physicalSpecular?: boolean;
|
|
107
112
|
/**
|
|
108
113
|
* How many point lights this build declares room for. `MAX_POINT_LIGHTS` when absent.
|
|
109
114
|
*
|
|
@@ -14,7 +14,7 @@ import { CLOTH_BINDING_GLSL } from '../clothBinding.js';
|
|
|
14
14
|
import { SKINNING_GLSL } from '../skinning.js';
|
|
15
15
|
import { SURFACE_GLSL } from './surface.js';
|
|
16
16
|
import { MAIN_GLSL } from './main.js';
|
|
17
|
-
import {
|
|
17
|
+
import { modelsGlsl } from './models.js';
|
|
18
18
|
import { AREA_LIGHT_GLSL } from './areaLight.js';
|
|
19
19
|
import { NORMAL_MAP_GLSL } from './normalMap.js';
|
|
20
20
|
import { DRIFT_LIGHT_GLSL } from './driftLight.js';
|
|
@@ -244,6 +244,15 @@ void main() {
|
|
|
244
244
|
#endif
|
|
245
245
|
#if INSTANCED
|
|
246
246
|
mat4 model = mat4(aInstanceModel0, aInstanceModel1, aInstanceModel2, aInstanceModel3);
|
|
247
|
+
/*
|
|
248
|
+
* **The bottom row is the instance's texture cell** (\`MeshInstances.uvRegions\`), which an
|
|
249
|
+
* affine placement leaves free: read, and rebuilt as the \`[0, 0, 0, 1]\` it stands for.
|
|
250
|
+
*/
|
|
251
|
+
vec4 instanceCell = vec4(model[0].w, model[1].w, model[2].w, model[3].w);
|
|
252
|
+
model[0].w = 0.0;
|
|
253
|
+
model[1].w = 0.0;
|
|
254
|
+
model[2].w = 0.0;
|
|
255
|
+
model[3].w = 1.0;
|
|
247
256
|
vec3 tint = aInstanceTint.rgb;
|
|
248
257
|
if (LIGHTMAP_REGIONS) tint = vec3(1.0);
|
|
249
258
|
#else
|
|
@@ -292,7 +301,12 @@ void main() {
|
|
|
292
301
|
vColor = aColor * tint;
|
|
293
302
|
vEmissive = aEmissive;
|
|
294
303
|
vSpecular = aSpecular;
|
|
304
|
+
#if INSTANCED
|
|
305
|
+
/* The instance's cell first, then the material's scale and offset. */
|
|
306
|
+
vUv = vec3((aUv.xy * instanceCell.xy + instanceCell.zw) * uUvScale + uUvOffset, aUv.z);
|
|
307
|
+
#else
|
|
295
308
|
vUv = vec3(aUv.xy * uUvScale + uUvOffset, aUv.z);
|
|
309
|
+
#endif
|
|
296
310
|
vEmissiveColor = aEmissiveColor;
|
|
297
311
|
vRoughness = aRoughness;
|
|
298
312
|
vGrain = aGrain;
|
|
@@ -456,7 +470,7 @@ export function flatFrag(options) {
|
|
|
456
470
|
DRIFT_LIGHT_GLSL,
|
|
457
471
|
SURFACE_EFFECTS_GLSL,
|
|
458
472
|
/* Depth zero and after the tangent frame and the lobes it calls; see models.ts. */
|
|
459
|
-
|
|
473
|
+
modelsGlsl(options.physicalSpecular ?? true),
|
|
460
474
|
/* After the models, whose answer to a rectangle it asks for. See areaLight.ts. */
|
|
461
475
|
AREA_LIGHT_GLSL,
|
|
462
476
|
MAIN_GLSL,
|
|
@@ -25,4 +25,10 @@ export declare const EMISSIVE_SHADOW_SHARE = 0.55;
|
|
|
25
25
|
* deliberately not this.
|
|
26
26
|
*/
|
|
27
27
|
export declare const MIN_LOBE_ALPHA = 0.01;
|
|
28
|
+
/**
|
|
29
|
+
* Karis's fit to the split-sum environment BRDF, as GLSL: the lit stage's, and the screen-space
|
|
30
|
+
* reflection's when a surface asks for its Fresnel (`ReflectiveSurface.fresnel`). One text, so the
|
|
31
|
+
* two cannot drift.
|
|
32
|
+
*/
|
|
33
|
+
export declare const ENV_BRDF_GLSL = "/**\n * The other half of the split-sum approximation: what fraction of an environment a surface returns.\n *\n * The convolution decides *what* a surface reflects at a given roughness; this decides *how much*.\n * Before it the amount was fresnel times one-minus-roughness, which is a curve somebody chose\n * standing in for an integral.\n *\n * Karis's analytic fit to the environment BRDF, so there is **no lookup texture and no texture\n * unit**: a few multiply-adds against roughness and the view angle. x scales the surface's own\n * reflectance at normal incidence and y is the additive grazing term, so a smooth dielectric at\n * f0 0.04 returns about 0.046 head-on and approaches 1 at the edge, which is what a dielectric\n * does. At roughness 1 it returns about 0.016 rather than the zero one-minus-roughness gave, which\n * is the substantive difference: a fully rough dielectric does reflect its surroundings.\n *\n * **It replaces the Fresnel factor as well as the thinning**, because the fit already contains the\n * angular dependence; multiplying by a separate Fresnel term would apply it twice.\n *\n * **How much this is worth was measured, and it is worth less than it looks on a dark room.**\n * On demo/dev/ibl.html?ladder=1 the whole ladder moved by at most 0.2 of 255 when the old term was\n * replaced. That is not the term failing: at high roughness the surface reads the coarsest levels\n * of the chain, and in a room of five dark walls and one bright one those levels are dark, so a\n * weight three times larger against a near-zero radiance is still near zero. It is worth much more\n * against a bright environment, which is what a loaded sky is and what no captured room here is.\n *\n * **A warning about reading that page, paid for once.** The ladder falls about five-fold from\n * mirror to rough, and that reads as energy being lost. It is not: a mirror concentrates the one\n * bright wall into a sharp image and a rough surface averages it against five dark ones, so the\n * falloff is the room's own content. The normalised falloff also happens to track one-minus-\n * roughness closely, which made the old term look like the cause \u2014 and removing that term entirely\n * changed nothing, which is what settled it. Perturb before believing a match.\n *\n * **What it costs** is a fit rather than the integral: the published error is around one per cent\n * of the tabulated term, far below what an eight-bit frame can show. **What would make it wrong**\n * is a material model this shader does not have \u2014 a clearcoat or a sheen lobe carries its own BRDF\n * and its own integral, and this fit is Trowbridge-Reitz with Smith masking and nothing else.\n */\nvec2 envBrdfApprox(float ndv, float roughness) {\n const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\n const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\n vec4 r = roughness * c0 + c1;\n float a004 = min(r.x * r.x, exp2(-9.28 * ndv)) * r.x + r.y;\n return vec2(-1.04, 1.04) * a004 + r.zw;\n}";
|
|
28
34
|
export declare const LOBES_GLSL: string;
|
|
@@ -27,6 +27,54 @@ export const EMISSIVE_SHADOW_SHARE = 0.55;
|
|
|
27
27
|
* deliberately not this.
|
|
28
28
|
*/
|
|
29
29
|
export const MIN_LOBE_ALPHA = 0.01;
|
|
30
|
+
/**
|
|
31
|
+
* Karis's fit to the split-sum environment BRDF, as GLSL: the lit stage's, and the screen-space
|
|
32
|
+
* reflection's when a surface asks for its Fresnel (`ReflectiveSurface.fresnel`). One text, so the
|
|
33
|
+
* two cannot drift.
|
|
34
|
+
*/
|
|
35
|
+
export const ENV_BRDF_GLSL = `/**
|
|
36
|
+
* The other half of the split-sum approximation: what fraction of an environment a surface returns.
|
|
37
|
+
*
|
|
38
|
+
* The convolution decides *what* a surface reflects at a given roughness; this decides *how much*.
|
|
39
|
+
* Before it the amount was fresnel times one-minus-roughness, which is a curve somebody chose
|
|
40
|
+
* standing in for an integral.
|
|
41
|
+
*
|
|
42
|
+
* Karis's analytic fit to the environment BRDF, so there is **no lookup texture and no texture
|
|
43
|
+
* unit**: a few multiply-adds against roughness and the view angle. x scales the surface's own
|
|
44
|
+
* reflectance at normal incidence and y is the additive grazing term, so a smooth dielectric at
|
|
45
|
+
* f0 0.04 returns about 0.046 head-on and approaches 1 at the edge, which is what a dielectric
|
|
46
|
+
* does. At roughness 1 it returns about 0.016 rather than the zero one-minus-roughness gave, which
|
|
47
|
+
* is the substantive difference: a fully rough dielectric does reflect its surroundings.
|
|
48
|
+
*
|
|
49
|
+
* **It replaces the Fresnel factor as well as the thinning**, because the fit already contains the
|
|
50
|
+
* angular dependence; multiplying by a separate Fresnel term would apply it twice.
|
|
51
|
+
*
|
|
52
|
+
* **How much this is worth was measured, and it is worth less than it looks on a dark room.**
|
|
53
|
+
* On demo/dev/ibl.html?ladder=1 the whole ladder moved by at most 0.2 of 255 when the old term was
|
|
54
|
+
* replaced. That is not the term failing: at high roughness the surface reads the coarsest levels
|
|
55
|
+
* of the chain, and in a room of five dark walls and one bright one those levels are dark, so a
|
|
56
|
+
* weight three times larger against a near-zero radiance is still near zero. It is worth much more
|
|
57
|
+
* against a bright environment, which is what a loaded sky is and what no captured room here is.
|
|
58
|
+
*
|
|
59
|
+
* **A warning about reading that page, paid for once.** The ladder falls about five-fold from
|
|
60
|
+
* mirror to rough, and that reads as energy being lost. It is not: a mirror concentrates the one
|
|
61
|
+
* bright wall into a sharp image and a rough surface averages it against five dark ones, so the
|
|
62
|
+
* falloff is the room's own content. The normalised falloff also happens to track one-minus-
|
|
63
|
+
* roughness closely, which made the old term look like the cause — and removing that term entirely
|
|
64
|
+
* changed nothing, which is what settled it. Perturb before believing a match.
|
|
65
|
+
*
|
|
66
|
+
* **What it costs** is a fit rather than the integral: the published error is around one per cent
|
|
67
|
+
* of the tabulated term, far below what an eight-bit frame can show. **What would make it wrong**
|
|
68
|
+
* is a material model this shader does not have — a clearcoat or a sheen lobe carries its own BRDF
|
|
69
|
+
* and its own integral, and this fit is Trowbridge-Reitz with Smith masking and nothing else.
|
|
70
|
+
*/
|
|
71
|
+
vec2 envBrdfApprox(float ndv, float roughness) {
|
|
72
|
+
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
|
|
73
|
+
const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
|
|
74
|
+
vec4 r = roughness * c0 + c1;
|
|
75
|
+
float a004 = min(r.x * r.x, exp2(-9.28 * ndv)) * r.x + r.y;
|
|
76
|
+
return vec2(-1.04, 1.04) * a004 + r.zw;
|
|
77
|
+
}`;
|
|
30
78
|
export const LOBES_GLSL = `float shadowReach(float distance, float maxDistance) {
|
|
31
79
|
return 1.0 - smoothstep(
|
|
32
80
|
maxDistance * ${POINT_SHADOW_FADE_START.toFixed(2)},
|
|
@@ -153,49 +201,7 @@ float sphereLobe(float ndh, float roughness, float sourceRadius, float dist) {
|
|
|
153
201
|
return energy * (w2 * w2) / max(d * d, 1e-8);
|
|
154
202
|
}
|
|
155
203
|
|
|
156
|
-
|
|
157
|
-
* The other half of the split-sum approximation: what fraction of an environment a surface returns.
|
|
158
|
-
*
|
|
159
|
-
* The convolution decides *what* a surface reflects at a given roughness; this decides *how much*.
|
|
160
|
-
* Before it the amount was fresnel times one-minus-roughness, which is a curve somebody chose
|
|
161
|
-
* standing in for an integral.
|
|
162
|
-
*
|
|
163
|
-
* Karis's analytic fit to the environment BRDF, so there is **no lookup texture and no texture
|
|
164
|
-
* unit**: a few multiply-adds against roughness and the view angle. x scales the surface's own
|
|
165
|
-
* reflectance at normal incidence and y is the additive grazing term, so a smooth dielectric at
|
|
166
|
-
* f0 0.04 returns about 0.046 head-on and approaches 1 at the edge, which is what a dielectric
|
|
167
|
-
* does. At roughness 1 it returns about 0.016 rather than the zero one-minus-roughness gave, which
|
|
168
|
-
* is the substantive difference: a fully rough dielectric does reflect its surroundings.
|
|
169
|
-
*
|
|
170
|
-
* **It replaces the Fresnel factor as well as the thinning**, because the fit already contains the
|
|
171
|
-
* angular dependence; multiplying by a separate Fresnel term would apply it twice.
|
|
172
|
-
*
|
|
173
|
-
* **How much this is worth was measured, and it is worth less than it looks on a dark room.**
|
|
174
|
-
* On demo/dev/ibl.html?ladder=1 the whole ladder moved by at most 0.2 of 255 when the old term was
|
|
175
|
-
* replaced. That is not the term failing: at high roughness the surface reads the coarsest levels
|
|
176
|
-
* of the chain, and in a room of five dark walls and one bright one those levels are dark, so a
|
|
177
|
-
* weight three times larger against a near-zero radiance is still near zero. It is worth much more
|
|
178
|
-
* against a bright environment, which is what a loaded sky is and what no captured room here is.
|
|
179
|
-
*
|
|
180
|
-
* **A warning about reading that page, paid for once.** The ladder falls about five-fold from
|
|
181
|
-
* mirror to rough, and that reads as energy being lost. It is not: a mirror concentrates the one
|
|
182
|
-
* bright wall into a sharp image and a rough surface averages it against five dark ones, so the
|
|
183
|
-
* falloff is the room's own content. The normalised falloff also happens to track one-minus-
|
|
184
|
-
* roughness closely, which made the old term look like the cause — and removing that term entirely
|
|
185
|
-
* changed nothing, which is what settled it. Perturb before believing a match.
|
|
186
|
-
*
|
|
187
|
-
* **What it costs** is a fit rather than the integral: the published error is around one per cent
|
|
188
|
-
* of the tabulated term, far below what an eight-bit frame can show. **What would make it wrong**
|
|
189
|
-
* is a material model this shader does not have — a clearcoat or a sheen lobe carries its own BRDF
|
|
190
|
-
* and its own integral, and this fit is Trowbridge-Reitz with Smith masking and nothing else.
|
|
191
|
-
*/
|
|
192
|
-
vec2 envBrdfApprox(float ndv, float roughness) {
|
|
193
|
-
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
|
|
194
|
-
const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
|
|
195
|
-
vec4 r = roughness * c0 + c1;
|
|
196
|
-
float a004 = min(r.x * r.x, exp2(-9.28 * ndv)) * r.x + r.y;
|
|
197
|
-
return vec2(-1.04, 1.04) * a004 + r.zw;
|
|
198
|
-
}
|
|
204
|
+
${ENV_BRDF_GLSL}
|
|
199
205
|
|
|
200
206
|
/**
|
|
201
207
|
* How much of a prefiltered environment a surface returns, with the light that bounces more than
|