@forgeax/engine-shader 0.1.7 → 0.1.19
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/README.md +34 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/ShaderRegistry.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +53 -2
- package/dist/index.mjs.map +1 -1
- package/dist/material-schemas.d.ts.map +1 -1
- package/package.json +6 -3
- package/src/ShaderRegistry.ts +50 -0
- package/src/__tests__/bloom-fxaa-tonemap.unit.test.ts +86 -12
- package/src/__tests__/default-standard-pbr-transmission.unit.test.ts +181 -0
- package/src/__tests__/lighting-punctual.unit.test.ts +1 -1
- package/src/__tests__/material-builtins.unit.test.ts +38 -1
- package/src/__tests__/material-contract.unit.test.ts +123 -0
- package/src/__tests__/motion-blur.unit.test.ts +44 -0
- package/src/__tests__/scene-temporal.unit.test.ts +23 -5
- package/src/__tests__/shader-manifest-transmission.unit.test.ts +75 -0
- package/src/__tests__/shader.unit.test.ts +43 -3
- package/src/__tests__/sprite-variants.unit.test.ts +19 -0
- package/src/__tests__/taa-resolve.unit.test.ts +75 -3
- package/src/__tests__/transmission-thickness-scale.unit.test.ts +19 -0
- package/src/common.wgsl +30 -30
- package/src/default-standard-pbr-skin.wgsl +27 -9
- package/src/default-standard-pbr.wgsl +209 -28
- package/src/fxaa.wgsl +5 -6
- package/src/index.ts +3 -0
- package/src/material-schemas.ts +7 -0
- package/src/motion-blur.wgsl +77 -0
- package/src/pbr-temporal.wgsl +15 -2
- package/src/scene-temporal.wgsl +54 -0
- package/src/shadow_caster.wgsl +27 -2
- package/src/sprite-lit.wgsl +5 -4
- package/src/sprite.wgsl +5 -4
- package/src/taa-resolve.wgsl +76 -81
- package/src/tonemap.wgsl +7 -9
- package/src/unlit.wgsl +6 -5
- package/dist/__tests__/atmosphere-background.test.d.ts +0 -2
- package/dist/__tests__/atmosphere-background.test.d.ts.map +0 -1
- package/dist/__tests__/atmosphere-cubemap-orientation.test.d.ts +0 -2
- package/dist/__tests__/atmosphere-cubemap-orientation.test.d.ts.map +0 -1
- package/dist/__tests__/atmosphere-preetham-numeric.test.d.ts +0 -2
- package/dist/__tests__/atmosphere-preetham-numeric.test.d.ts.map +0 -1
- package/dist/__tests__/atmosphere-preetham-red.test.d.ts +0 -2
- package/dist/__tests__/atmosphere-preetham-red.test.d.ts.map +0 -1
- package/dist/__tests__/atmosphere-preetham.test.d.ts +0 -2
- package/dist/__tests__/atmosphere-preetham.test.d.ts.map +0 -1
- package/dist/__tests__/atmosphere-three-r184-reference.test.d.ts +0 -2
- package/dist/__tests__/atmosphere-three-r184-reference.test.d.ts.map +0 -1
- package/dist/__tests__/bloom-fxaa-tonemap.unit.test.d.ts +0 -2
- package/dist/__tests__/bloom-fxaa-tonemap.unit.test.d.ts.map +0 -1
- package/dist/__tests__/builtin-texture-sampling-contract.test.d.ts +0 -2
- package/dist/__tests__/builtin-texture-sampling-contract.test.d.ts.map +0 -1
- package/dist/__tests__/default-standard-pbr-alpha.unit.test.d.ts +0 -2
- package/dist/__tests__/default-standard-pbr-alpha.unit.test.d.ts.map +0 -1
- package/dist/__tests__/deferred-lighting-ssao.test.d.ts +0 -2
- package/dist/__tests__/deferred-lighting-ssao.test.d.ts.map +0 -1
- package/dist/__tests__/fog-oracle.unit.test.d.ts +0 -2
- package/dist/__tests__/fog-oracle.unit.test.d.ts.map +0 -1
- package/dist/__tests__/fog-orthographic-ray.unit.test.d.ts +0 -2
- package/dist/__tests__/fog-orthographic-ray.unit.test.d.ts.map +0 -1
- package/dist/__tests__/fog-producer-matrix.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-producer-matrix.integration.test.d.ts.map +0 -1
- package/dist/__tests__/hdrp-ssao-compile.test.d.ts +0 -2
- package/dist/__tests__/hdrp-ssao-compile.test.d.ts.map +0 -1
- package/dist/__tests__/ibl-irradiance.unit.test.d.ts +0 -2
- package/dist/__tests__/ibl-irradiance.unit.test.d.ts.map +0 -1
- package/dist/__tests__/ibl-sampling.unit.test.d.ts +0 -2
- package/dist/__tests__/ibl-sampling.unit.test.d.ts.map +0 -1
- package/dist/__tests__/lighting-punctual.unit.test.d.ts +0 -2
- package/dist/__tests__/lighting-punctual.unit.test.d.ts.map +0 -1
- package/dist/__tests__/material-artifact-dedup.unit.test.d.ts +0 -2
- package/dist/__tests__/material-artifact-dedup.unit.test.d.ts.map +0 -1
- package/dist/__tests__/material-builtins.unit.test.d.ts +0 -2
- package/dist/__tests__/material-builtins.unit.test.d.ts.map +0 -1
- package/dist/__tests__/material-contract.unit.test.d.ts +0 -2
- package/dist/__tests__/material-contract.unit.test.d.ts.map +0 -1
- package/dist/__tests__/material-derived-builtins.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-builtins.integration.test.d.ts.map +0 -1
- package/dist/__tests__/points-lines-shader.unit.test.d.ts +0 -2
- package/dist/__tests__/points-lines-shader.unit.test.d.ts.map +0 -1
- package/dist/__tests__/public-surface.unit.test.d.ts +0 -2
- package/dist/__tests__/public-surface.unit.test.d.ts.map +0 -1
- package/dist/__tests__/scene-temporal.unit.test.d.ts +0 -2
- package/dist/__tests__/scene-temporal.unit.test.d.ts.map +0 -1
- package/dist/__tests__/shader-registry-transaction.unit.test.d.ts +0 -2
- package/dist/__tests__/shader-registry-transaction.unit.test.d.ts.map +0 -1
- package/dist/__tests__/shader.unit.test.d.ts +0 -2
- package/dist/__tests__/shader.unit.test.d.ts.map +0 -1
- package/dist/__tests__/sprite-lit-shader.test.d.ts +0 -2
- package/dist/__tests__/sprite-lit-shader.test.d.ts.map +0 -1
- package/dist/__tests__/sprite-variants.unit.test.d.ts +0 -2
- package/dist/__tests__/sprite-variants.unit.test.d.ts.map +0 -1
- package/dist/__tests__/taa-resolve.unit.test.d.ts +0 -2
- package/dist/__tests__/taa-resolve.unit.test.d.ts.map +0 -1
- package/dist/__tests__/transparent-pbr.unit.test.d.ts +0 -2
- package/dist/__tests__/transparent-pbr.unit.test.d.ts.map +0 -1
- package/dist/__tests__/vertex-color-variant.unit.test.d.ts +0 -2
- package/dist/__tests__/vertex-color-variant.unit.test.d.ts.map +0 -1
package/src/shadow_caster.wgsl
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#pragma variant_axis STORAGE_BUFFER_AVAILABLE
|
|
2
|
+
#pragma variant_axis SKINNING_DISABLED
|
|
2
3
|
|
|
3
4
|
// @forgeax/engine-shader shadow_caster.wgsl
|
|
4
5
|
// feat-20260520-directional-light-shadow-mapping M1c / w9 (D-9 / AC-09):
|
|
@@ -20,15 +21,28 @@
|
|
|
20
21
|
// @group(2) binding(0) meshes : array<Mesh> -- common.wgsl
|
|
21
22
|
// @group(3) binding(0) instances : array<InstanceData> -- common.wgsl
|
|
22
23
|
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
24
|
+
// SKINNING_DISABLED=true consumes the ordinary 12F mesh layout; the explicit
|
|
25
|
+
// false variant consumes JOINTS_0 / WEIGHTS_0 from the same 18F layout as pbr-skin and
|
|
26
|
+
// projects the animated world-space palette result into the shadow view.
|
|
25
27
|
|
|
26
28
|
#import forgeax_view::common::{View, Mesh, InstanceData, ShadowCasterCascade, view, shadowCasterCascade, meshes, instances}
|
|
27
29
|
|
|
28
30
|
struct VsInput {
|
|
29
31
|
@location(0) position : vec3<f32>,
|
|
32
|
+
#if SKINNING_DISABLED == false
|
|
33
|
+
@location(4) skinIndex : vec4<u32>,
|
|
34
|
+
@location(5) skinWeight : vec4<f32>,
|
|
35
|
+
#endif
|
|
30
36
|
};
|
|
31
37
|
|
|
38
|
+
#if SKINNING_DISABLED == false
|
|
39
|
+
#if STORAGE_BUFFER_AVAILABLE == true
|
|
40
|
+
@group(2) @binding(1) var<storage, read> palette : array<mat4x4<f32>>;
|
|
41
|
+
#else
|
|
42
|
+
@group(2) @binding(1) var<uniform> palette : array<mat4x4<f32>, 255>;
|
|
43
|
+
#endif
|
|
44
|
+
#endif
|
|
45
|
+
|
|
32
46
|
fn _cascadeLightViewProj(layer : u32) -> mat4x4<f32> {
|
|
33
47
|
switch (layer) {
|
|
34
48
|
case 0u: { return view.lightViewProj_A; }
|
|
@@ -40,7 +54,18 @@ fn _cascadeLightViewProj(layer : u32) -> mat4x4<f32> {
|
|
|
40
54
|
|
|
41
55
|
@vertex
|
|
42
56
|
fn vs_main(in : VsInput, @builtin(instance_index) idx : u32) -> @builtin(position) vec4<f32> {
|
|
57
|
+
#if SKINNING_DISABLED == false
|
|
58
|
+
let skinMatrix = palette[in.skinIndex.x] * in.skinWeight.x +
|
|
59
|
+
palette[in.skinIndex.y] * in.skinWeight.y +
|
|
60
|
+
palette[in.skinIndex.z] * in.skinWeight.z +
|
|
61
|
+
palette[in.skinIndex.w] * in.skinWeight.w;
|
|
62
|
+
// Palette entries are jointWorld * inverseBind and therefore already
|
|
63
|
+
// produce world-space positions. Applying meshes[0].worldFromLocal again
|
|
64
|
+
// would double-transform a parented skinned entity.
|
|
65
|
+
let worldPos = skinMatrix * vec4<f32>(in.position, 1.0);
|
|
66
|
+
#else
|
|
43
67
|
let worldPos = meshes[0].worldFromLocal * instances[idx].localFromInstance * vec4<f32>(in.position, 1.0);
|
|
68
|
+
#endif
|
|
44
69
|
// feat-20260625-spot-light-shadow-mapping M2 / w10 (D-1): spot shadow passes
|
|
45
70
|
// set `isSpot = 1u` and write their perspective matrix into
|
|
46
71
|
// `spotLightViewProj`; directional cascade passes keep `isSpot = 0u` and read
|
package/src/sprite-lit.wgsl
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#pragma variant_axis STORAGE_BUFFER_AVAILABLE
|
|
2
2
|
#define_import_path forgeax_material::sprite-lit
|
|
3
3
|
|
|
4
|
-
#import forgeax_view::common::{View, FogViewParams, FogRay, Mesh, InstanceData, PointLight, SpotLight, view, meshes, instances, pointLightsBuffer, spotLightsBuffer, sampleMaterialTexture
|
|
4
|
+
#import forgeax_view::common::{View, FogViewParams, FogRay, Mesh, InstanceData, PointLight, SpotLight, view, meshes, instances, pointLightsBuffer, spotLightsBuffer, sampleMaterialTexture}
|
|
5
|
+
#import forgeax_scene_temporal::{packSceneTemporalV1}
|
|
5
6
|
#import forgeax_view::fog::{apply_fog}
|
|
6
7
|
|
|
7
8
|
// @forgeax/engine-shader - sprite-lit.wgsl
|
|
@@ -272,8 +273,8 @@ fn fs_main_hdr(in : VsOut) -> @location(0) vec4<f32> {
|
|
|
272
273
|
struct TemporalVsOut {
|
|
273
274
|
@builtin(position) clip : vec4<f32>,
|
|
274
275
|
@location(0) uvAtlas : vec2<f32>,
|
|
275
|
-
@location(1) @interpolate(
|
|
276
|
-
@location(2) @interpolate(
|
|
276
|
+
@location(1) @interpolate(perspective) currentClip : vec4<f32>,
|
|
277
|
+
@location(2) @interpolate(perspective) previousClip : vec4<f32>,
|
|
277
278
|
};
|
|
278
279
|
|
|
279
280
|
@vertex
|
|
@@ -301,7 +302,7 @@ fn fs_temporal(in : TemporalVsOut) -> @location(0) vec4<f32> {
|
|
|
301
302
|
if (alpha <= 0.0) {
|
|
302
303
|
discard;
|
|
303
304
|
}
|
|
304
|
-
return
|
|
305
|
+
return packSceneTemporalV1(in.currentClip, in.previousClip, view.temporalProjection, 1.0);
|
|
305
306
|
}
|
|
306
307
|
// sprite-lit needs at least one light in the scene to be visible; for unlit
|
|
307
308
|
// sprites use forgeax::sprite (1 string change in MaterialAsset).
|
package/src/sprite.wgsl
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
#pragma variant_axis STORAGE_BUFFER_AVAILABLE
|
|
3
3
|
#pragma variant_axis PER_INSTANCE_REGION
|
|
4
4
|
|
|
5
|
-
#import forgeax_view::common::{View, FogViewParams, FogRay, Mesh, InstanceData, view, meshes, instances, sampleMaterialTexture
|
|
5
|
+
#import forgeax_view::common::{View, FogViewParams, FogRay, Mesh, InstanceData, view, meshes, instances, sampleMaterialTexture}
|
|
6
|
+
#import forgeax_scene_temporal::{packSceneTemporalV1}
|
|
6
7
|
#import forgeax_view::fog::{apply_fog}
|
|
7
8
|
|
|
8
9
|
// @forgeax/engine-shader - sprite.wgsl (feat-20260520-2d-sprite-layer-mvp /
|
|
@@ -330,8 +331,8 @@ fn fs_main_hdr(in : VsOut) -> @location(0) vec4<f32> {
|
|
|
330
331
|
struct TemporalVsOut {
|
|
331
332
|
@builtin(position) clip : vec4<f32>,
|
|
332
333
|
@location(0) uvAtlas : vec2<f32>,
|
|
333
|
-
@location(1) @interpolate(
|
|
334
|
-
@location(2) @interpolate(
|
|
334
|
+
@location(1) @interpolate(perspective) currentClip : vec4<f32>,
|
|
335
|
+
@location(2) @interpolate(perspective) previousClip : vec4<f32>,
|
|
335
336
|
};
|
|
336
337
|
|
|
337
338
|
@vertex
|
|
@@ -359,7 +360,7 @@ fn fs_temporal(in : TemporalVsOut) -> @location(0) vec4<f32> {
|
|
|
359
360
|
if (alpha <= 0.0) {
|
|
360
361
|
discard;
|
|
361
362
|
}
|
|
362
|
-
return
|
|
363
|
+
return packSceneTemporalV1(in.currentClip, in.previousClip, view.temporalProjection, 1.0);
|
|
363
364
|
}
|
|
364
365
|
// sprite is unlit; do NOT read the directional-light fields of the View
|
|
365
366
|
// UBO -- same SSOT hard rule as the header comment above; R5 mitigation.
|
package/src/taa-resolve.wgsl
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
#define_import_path forgeax_view::taa_resolve
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
// Keep the fragment input shape explicit for compilers that tree-shake imported
|
|
4
|
+
// type declarations before resolving the vertex entry point.
|
|
5
|
+
struct FullscreenOutput {
|
|
6
|
+
@builtin(position) position : vec4<f32>,
|
|
7
|
+
@location(0) uv : vec2<f32>,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
fn fullscreen_triangle(vertex_index : u32) -> FullscreenOutput {
|
|
11
|
+
var x : f32 = -1.0;
|
|
12
|
+
var y : f32 = -1.0;
|
|
13
|
+
if (vertex_index == 1u) {
|
|
14
|
+
x = 3.0;
|
|
15
|
+
}
|
|
16
|
+
if (vertex_index == 2u) {
|
|
17
|
+
y = 3.0;
|
|
18
|
+
}
|
|
19
|
+
let u : f32 = (x + 1.0) * 0.5;
|
|
20
|
+
let v : f32 = 1.0 - (y + 1.0) * 0.5;
|
|
21
|
+
var out : FullscreenOutput;
|
|
22
|
+
out.position = vec4<f32>(x, y, 0.0, 1.0);
|
|
23
|
+
out.uv = vec2<f32>(u, v);
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
5
26
|
|
|
6
27
|
struct TaaResolveParams {
|
|
7
28
|
currentJitterUv : vec2<f32>,
|
|
@@ -14,12 +35,15 @@ struct TaaResolveOutput {
|
|
|
14
35
|
@location(1) temporal : vec4<f32>,
|
|
15
36
|
};
|
|
16
37
|
|
|
17
|
-
@group(
|
|
18
|
-
@group(
|
|
19
|
-
@group(
|
|
20
|
-
@group(
|
|
21
|
-
@group(
|
|
22
|
-
@group(
|
|
38
|
+
@group(1) @binding(0) var currentColor : texture_2d<f32>;
|
|
39
|
+
@group(1) @binding(1) var currentSampler : sampler;
|
|
40
|
+
@group(1) @binding(2) var historyColor : texture_2d<f32>;
|
|
41
|
+
@group(1) @binding(3) var historySampler : sampler;
|
|
42
|
+
@group(1) @binding(4) var historyTemporal : texture_2d<f32>;
|
|
43
|
+
@group(1) @binding(5) var temporalSampler : sampler;
|
|
44
|
+
@group(1) @binding(6) var currentTemporal : texture_2d<f32>;
|
|
45
|
+
@group(1) @binding(7) var currentTemporalSampler : sampler;
|
|
46
|
+
@group(1) @binding(8) var<uniform> params : TaaResolveParams;
|
|
23
47
|
|
|
24
48
|
fn rgbToYCoCg(rgb : vec3<f32>) -> vec3<f32> {
|
|
25
49
|
return vec3<f32>(
|
|
@@ -37,93 +61,64 @@ fn luminance(rgb : vec3<f32>) -> f32 {
|
|
|
37
61
|
return dot(rgb, vec3<f32>(0.2126, 0.7152, 0.0722));
|
|
38
62
|
}
|
|
39
63
|
|
|
40
|
-
fn
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// packed motion is already unjittered currentUv - previousUv.
|
|
44
|
-
return textureSampleLevel(currentColor, historySampler, uv + params.currentJitterUv, 0.0);
|
|
64
|
+
fn closestCurrentTemporal(pixel : vec2<i32>, dimensions : vec2<i32>) -> vec4<f32> {
|
|
65
|
+
let clamped = clamp(pixel, vec2<i32>(0), dimensions - vec2<i32>(1));
|
|
66
|
+
return textureLoad(currentTemporal, clamped, 0);
|
|
45
67
|
}
|
|
46
68
|
|
|
47
|
-
fn
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
let candidate = textureLoad(currentTemporal, samplePixel, 0);
|
|
54
|
-
if candidate.z >= 0.0 && candidate.z < closestDepth {
|
|
55
|
-
closest = candidate;
|
|
56
|
-
closestDepth = candidate.z;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return closest;
|
|
69
|
+
fn neighborhoodSquareMean(uv : vec2<f32>, texel : vec2<f32>) -> vec3<f32> {
|
|
70
|
+
let north = textureSampleLevel(currentColor, currentSampler, uv + vec2<f32>(0.0, texel.y), 0.0).rgb;
|
|
71
|
+
let south = textureSampleLevel(currentColor, currentSampler, uv - vec2<f32>(0.0, texel.y), 0.0).rgb;
|
|
72
|
+
let east = textureSampleLevel(currentColor, currentSampler, uv + vec2<f32>(texel.x, 0.0), 0.0).rgb;
|
|
73
|
+
let west = textureSampleLevel(currentColor, currentSampler, uv - vec2<f32>(texel.x, 0.0), 0.0).rgb;
|
|
74
|
+
return (north + south + east + west) * 0.25;
|
|
61
75
|
}
|
|
62
76
|
|
|
63
77
|
@vertex
|
|
64
|
-
fn
|
|
78
|
+
fn vs_main(@builtin(vertex_index) vertexIndex : u32) -> FullscreenOutput {
|
|
65
79
|
return fullscreen_triangle(vertexIndex);
|
|
66
80
|
}
|
|
67
81
|
|
|
68
|
-
@fragment
|
|
69
82
|
fn fs_taa_resolve(in : FullscreenOutput) -> TaaResolveOutput {
|
|
70
|
-
let dimensions = vec2<i32>(textureDimensions(currentColor));
|
|
71
|
-
let
|
|
72
|
-
let current =
|
|
83
|
+
let dimensions = vec2<i32>(textureDimensions(currentColor, 0));
|
|
84
|
+
let texel = 1.0 / vec2<f32>(dimensions);
|
|
85
|
+
let current = textureSampleLevel(currentColor, currentSampler, in.uv + params.currentJitterUv, 0.0);
|
|
86
|
+
let pixel = vec2<i32>(in.uv * vec2<f32>(dimensions));
|
|
73
87
|
let temporal = closestCurrentTemporal(pixel, dimensions);
|
|
74
|
-
|
|
75
|
-
var output : TaaResolveOutput;
|
|
76
|
-
output.temporal = temporal;
|
|
77
|
-
output.color = current;
|
|
78
|
-
|
|
79
88
|
let historyUv = in.uv - temporal.xy;
|
|
80
|
-
let historyInBounds = all(historyUv >= vec2<f32>(0.0)) && all(historyUv
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let previousTemporal = textureSampleLevel(historyTemporal, historySampler, historyUv, 0.0);
|
|
89
|
+
let historyInBounds = all(historyUv >= vec2<f32>(0.0)) && all(historyUv <= vec2<f32>(1.0));
|
|
90
|
+
let history = textureSampleLevel(historyColor, historySampler, historyUv, 0.0);
|
|
91
|
+
let previousTemporal = textureSampleLevel(historyTemporal, temporalSampler, historyUv, 0.0);
|
|
86
92
|
let depthDelta = abs(previousTemporal.z - temporal.z);
|
|
87
|
-
let depthThreshold =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
neighborhoodMin = min(neighborhoodMin, sampleValue);
|
|
101
|
-
neighborhoodMax = max(neighborhoodMax, sampleValue);
|
|
102
|
-
neighborhoodMean += sampleValue;
|
|
103
|
-
neighborhoodSquareMean += sampleValue * sampleValue;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
neighborhoodMean /= 9.0;
|
|
107
|
-
neighborhoodSquareMean /= 9.0;
|
|
108
|
-
let sigma = sqrt(max(neighborhoodSquareMean - neighborhoodMean * neighborhoodMean, vec3<f32>(0.0)));
|
|
109
|
-
let clipMin = max(neighborhoodMin, neighborhoodMean - sigma * 1.25);
|
|
110
|
-
let clipMax = min(neighborhoodMax, neighborhoodMean + sigma * 1.25);
|
|
111
|
-
|
|
112
|
-
let sampledHistory = textureSampleLevel(historyColor, historySampler, historyUv, 0.0);
|
|
113
|
-
let clippedHistoryRgb = yCoCgToRgb(clamp(rgbToYCoCg(sampledHistory.rgb), clipMin, clipMax));
|
|
114
|
-
let velocityFactor = 1.0 - clamp(length(temporal.xy) * 64.0, 0.0, 1.0);
|
|
93
|
+
let depthThreshold = 0.0025 + temporal.z * 0.01;
|
|
94
|
+
let rejected =
|
|
95
|
+
params.historyValid == 0u ||
|
|
96
|
+
!historyInBounds ||
|
|
97
|
+
temporal.z < 0.0 ||
|
|
98
|
+
previousTemporal.z < 0.0 ||
|
|
99
|
+
depthDelta > depthThreshold;
|
|
100
|
+
let neighborhood = neighborhoodSquareMean(in.uv, texel);
|
|
101
|
+
let neighborhoodDelta = abs(luminance(current.rgb) - luminance(neighborhood));
|
|
102
|
+
let clipPadding = vec3<f32>(0.5);
|
|
103
|
+
let clipMin = rgbToYCoCg(min(current.rgb, neighborhood - vec3<f32>(neighborhoodDelta) - clipPadding));
|
|
104
|
+
let clipMax = rgbToYCoCg(max(current.rgb, neighborhood + vec3<f32>(neighborhoodDelta) + clipPadding));
|
|
105
|
+
let clippedHistoryRgb = yCoCgToRgb(clamp(rgbToYCoCg(history.rgb), clipMin, clipMax));
|
|
115
106
|
let reactiveFactor = 1.0 - clamp(temporal.w, 0.0, 1.0);
|
|
107
|
+
let velocityFactor = 1.0 - clamp(length(temporal.xy) * 64.0, 0.0, 1.0);
|
|
116
108
|
let depthFactor = 1.0 - clamp(depthDelta / depthThreshold, 0.0, 1.0);
|
|
117
|
-
let
|
|
118
|
-
let historyLuma = luminance(clippedHistoryRgb);
|
|
119
|
-
let lumaDelta = abs(historyLuma - currentLuma);
|
|
120
|
-
let unbiasedLumaDelta = clamp(lumaDelta / max(max(currentLuma, historyLuma), 0.2), 0.0, 1.0);
|
|
109
|
+
let unbiasedLumaDelta = clamp(abs(luminance(current.rgb) - luminance(history.rgb)), 0.0, 1.0);
|
|
121
110
|
let lumaFactor = (1.0 - unbiasedLumaDelta) * (1.0 - unbiasedLumaDelta);
|
|
122
111
|
let fixedPresetWeight = mix(0.88, 0.97, lumaFactor);
|
|
123
|
-
let
|
|
124
|
-
let
|
|
125
|
-
let
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
112
|
+
let progressiveWeight = select(fixedPresetWeight, 0.0, params.temporalFrameIndex < 8u);
|
|
113
|
+
let historyWeight = progressiveWeight * reactiveFactor * velocityFactor * depthFactor;
|
|
114
|
+
let resolved = select(mix(current.rgb, clippedHistoryRgb, historyWeight), current.rgb, rejected);
|
|
115
|
+
return TaaResolveOutput(
|
|
116
|
+
vec4<f32>(resolved, current.a),
|
|
117
|
+
temporal,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@fragment
|
|
122
|
+
fn fs_main(in : FullscreenOutput) -> TaaResolveOutput {
|
|
123
|
+
return fs_taa_resolve(in);
|
|
129
124
|
}
|
package/src/tonemap.wgsl
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#define_import_path forgeax_view::tonemap
|
|
2
2
|
|
|
3
|
-
// @forgeax/engine-shader - Three r184
|
|
3
|
+
// @forgeax/engine-shader - Three r184 Output Transform module.
|
|
4
4
|
//
|
|
5
5
|
// The public modes and formulas are the Three.js r184 oracle. The numeric
|
|
6
6
|
// values are the binding contract mirrored by TONEMAP_SHADER_MODE in tonemap.ts.
|
|
@@ -153,8 +153,7 @@ fn tonemapNeutral(color : vec3<f32>) -> vec3<f32> {
|
|
|
153
153
|
|
|
154
154
|
@fragment
|
|
155
155
|
fn fs_main(in : FullscreenOutput) -> @location(0) vec4<f32> {
|
|
156
|
-
//
|
|
157
|
-
// linearLdrColorDomain: the output pass emits the display-target domain.
|
|
156
|
+
// Output Transform consumes linear HDR and emits display-encoded color.
|
|
158
157
|
let source = textureSample(hdr, samp, in.uv);
|
|
159
158
|
let sample : vec3<f32> = source.rgb;
|
|
160
159
|
let exposed : vec3<f32> = sample * params.exposure;
|
|
@@ -167,11 +166,10 @@ fn fs_main(in : FullscreenOutput) -> @location(0) vec4<f32> {
|
|
|
167
166
|
case 5u: { mapped = tonemapAgx(exposed); }
|
|
168
167
|
case 6u: { mapped = tonemapNeutral(exposed); }
|
|
169
168
|
case 7u: { mapped = tonemapReinhard(exposed); }
|
|
170
|
-
// Mode 0
|
|
171
|
-
|
|
172
|
-
default: { mapped = linearToSrgbOetf(exposed); }
|
|
169
|
+
// Mode 0 skips the tone curve but still performs the output conversion.
|
|
170
|
+
default: { mapped = sample; }
|
|
173
171
|
}
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
return vec4<f32>(
|
|
172
|
+
// Every public mode reaches exactly one shared sRGB OETF.
|
|
173
|
+
let encoded = linearToSrgbOetf(mapped);
|
|
174
|
+
return vec4<f32>(encoded, source.a);
|
|
177
175
|
}
|
package/src/unlit.wgsl
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#define_import_path forgeax_material::unlit
|
|
2
|
-
#import forgeax_view::common::{View, FogViewParams, FogRay, Mesh, InstanceData, view, meshes, instances, sampleMaterialTextureLinear
|
|
2
|
+
#import forgeax_view::common::{View, FogViewParams, FogRay, Mesh, InstanceData, view, meshes, instances, sampleMaterialTextureLinear}
|
|
3
|
+
#import forgeax_scene_temporal::{packSceneTemporalV1}
|
|
3
4
|
#import forgeax_view::fog::{apply_fog}
|
|
4
5
|
|
|
5
6
|
#pragma variant_axis STORAGE_BUFFER_AVAILABLE
|
|
@@ -135,8 +136,8 @@ fn fs_main(in : VsOut) -> @location(0) vec4<f32> {
|
|
|
135
136
|
struct TemporalVsOut {
|
|
136
137
|
@builtin(position) clip : vec4<f32>,
|
|
137
138
|
@location(0) uv : vec2<f32>,
|
|
138
|
-
@location(1) @interpolate(
|
|
139
|
-
@location(2) @interpolate(
|
|
139
|
+
@location(1) @interpolate(perspective) currentClip : vec4<f32>,
|
|
140
|
+
@location(2) @interpolate(perspective) previousClip : vec4<f32>,
|
|
140
141
|
#ifdef VERTEX_COLOR_AVAILABLE
|
|
141
142
|
@location(14) color : vec4<f32>,
|
|
142
143
|
#endif
|
|
@@ -178,9 +179,9 @@ fn fs_temporal(in : TemporalVsOut) -> @location(0) vec4<f32> {
|
|
|
178
179
|
if (material.alphaCutoff > 0.0 && alpha < material.alphaCutoff) {
|
|
179
180
|
discard;
|
|
180
181
|
}
|
|
181
|
-
var reactive =
|
|
182
|
+
var reactive = 0.0;
|
|
182
183
|
#if STORAGE_BUFFER_AVAILABLE == true
|
|
183
184
|
reactive = meshes[0].temporal.x;
|
|
184
185
|
#endif
|
|
185
|
-
return
|
|
186
|
+
return packSceneTemporalV1(in.currentClip, in.previousClip, view.temporalProjection, reactive);
|
|
186
187
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atmosphere-background.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atmosphere-background.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atmosphere-cubemap-orientation.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atmosphere-cubemap-orientation.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atmosphere-preetham-numeric.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atmosphere-preetham-numeric.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atmosphere-preetham-red.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atmosphere-preetham-red.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atmosphere-preetham.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atmosphere-preetham.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atmosphere-three-r184-reference.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atmosphere-three-r184-reference.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bloom-fxaa-tonemap.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bloom-fxaa-tonemap.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-texture-sampling-contract.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/builtin-texture-sampling-contract.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"default-standard-pbr-alpha.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/default-standard-pbr-alpha.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deferred-lighting-ssao.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/deferred-lighting-ssao.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fog-oracle.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fog-oracle.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fog-orthographic-ray.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fog-orthographic-ray.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fog-producer-matrix.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fog-producer-matrix.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hdrp-ssao-compile.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/hdrp-ssao-compile.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ibl-irradiance.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ibl-irradiance.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ibl-sampling.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ibl-sampling.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lighting-punctual.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/lighting-punctual.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"material-artifact-dedup.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/material-artifact-dedup.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"material-builtins.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/material-builtins.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"material-contract.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/material-contract.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"material-derived-builtins.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/material-derived-builtins.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"points-lines-shader.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/points-lines-shader.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"public-surface.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/public-surface.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scene-temporal.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scene-temporal.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shader-registry-transaction.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/shader-registry-transaction.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shader.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/shader.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sprite-lit-shader.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sprite-lit-shader.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sprite-variants.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sprite-variants.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"taa-resolve.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/taa-resolve.unit.test.ts"],"names":[],"mappings":""}
|