@forgeax/engine-shader 0.1.23 → 0.1.25
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 +110 -4
- package/dist/ShaderRegistry.d.ts.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +59 -55
- package/dist/index.mjs.map +1 -1
- package/dist/material/artifact-registry.d.ts +1 -0
- package/dist/material/artifact-registry.d.ts.map +1 -1
- package/dist/material-schemas.d.ts +31 -0
- package/dist/material-schemas.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ShaderRegistry.ts +0 -17
- package/src/__tests__/builtin-texture-sampling-contract.test.ts +10 -1
- package/src/__tests__/default-standard-pbr-alpha.unit.test.ts +9 -3
- package/src/__tests__/default-standard-pbr-transmission.unit.test.ts +48 -166
- package/src/__tests__/deferred-lighting-ssao.test.ts +7 -4
- package/src/__tests__/ibl-irradiance.unit.test.ts +9 -0
- package/src/__tests__/lighting-directional.unit.test.ts +36 -0
- package/src/__tests__/lighting-punctual.unit.test.ts +12 -4
- package/src/__tests__/material-builtins.unit.test.ts +21 -3
- package/src/__tests__/material-contract.unit.test.ts +131 -17
- package/src/__tests__/physical-clearcoat.unit.test.ts +65 -0
- package/src/__tests__/probe-lighting-composition.unit.test.ts +3 -2
- package/src/__tests__/shader-manifest-transmission.unit.test.ts +8 -10
- package/src/__tests__/shader.unit.test.ts +52 -87
- package/src/__tests__/spot-cookie-composition.unit.test.ts +2 -1
- package/src/__tests__/standard-pbr-webgl2-interface.unit.test.ts +33 -0
- package/src/__tests__/standard-physical-layer.unit.test.ts +16 -0
- package/src/__tests__/standard-surface-pass-evaluation.integration.test.ts +38 -0
- package/src/__tests__/standard-webgl2-varying-budget.unit.test.ts +17 -0
- package/src/__tests__/surface-lighting-provenance.integration.test.ts +59 -0
- package/src/__tests__/surface-pass-templates.integration.test.ts +28 -0
- package/src/__tests__/surface-v1-negative.unit.test.ts +37 -0
- package/src/__tests__/surface-v1.unit.test.ts +83 -0
- package/src/__tests__/transmission-thickness-scale.unit.test.ts +2 -6
- package/src/__tests__/vertex-color-variant.unit.test.ts +16 -5
- package/src/default-standard-pbr-skin.wgsl +704 -192
- package/src/default-standard-pbr.wgsl +563 -279
- package/src/default_standard_surface.wgsl +88 -0
- package/src/hdrp-cluster-forward.wgsl +225 -0
- package/src/ibl-irradiance.wgsl +43 -8
- package/src/ibl-prefilter.wgsl +13 -3
- package/src/ibl-shared.wgsl +9 -2
- package/src/index.ts +37 -3
- package/src/lighting-directional.wgsl +3 -1
- package/src/lighting-spot-modifiers.wgsl +8 -1
- package/src/lighting-spot-projector.wgsl +31 -0
- package/src/material/artifact-registry.ts +20 -1
- package/src/material/artifact-types.ts +2 -2
- package/src/material/physical/anisotropy.wgsl +26 -0
- package/src/material/physical/clearcoat.wgsl +24 -0
- package/src/material/physical/iridescence.wgsl +23 -0
- package/src/material/physical/sheen.wgsl +17 -0
- package/src/material/standard-physical-layer.wgsl +12 -0
- package/src/material-schemas.ts +65 -30
- package/src/register-default-standard-pbr-skin.ts +2 -2
- package/src/shadow_caster.wgsl +80 -6
- package/src/standard-cluster.wgsl +1 -36
- package/src/surface_v1.wgsl +26 -0
- package/src/unlit.wgsl +12 -0
|
@@ -1,13 +1,31 @@
|
|
|
1
|
+
#pragma material_slot surface
|
|
2
|
+
#import forgeax_material::slot::surface::{evaluate_surface}
|
|
3
|
+
#import forgeax_material::surface_v1::{SurfaceInput, SurfaceData}
|
|
1
4
|
#import forgeax_view::common::{View, Mesh, InstanceData, view, meshes, instances, shadowMap, shadowSampler, sampleMaterialTexture}
|
|
2
5
|
#import forgeax_scene_temporal::{sceneViewZ}
|
|
6
|
+
#ifdef EXTENDED_LIGHTING_AVAILABLE
|
|
7
|
+
#import forgeax_view::common::{spotModifierSampler, iesProfileTexture, cookieTexture, cookieMatrices}
|
|
8
|
+
#endif
|
|
3
9
|
#import forgeax_pbr::temporal::{projectPbrSceneTemporal}
|
|
4
10
|
#import forgeax_pbr::brdf::{f_schlick, v_smith, d_ggx}
|
|
5
|
-
#import forgeax_pbr::ibl_sampling::{sampleIblDiffuse, sampleIblSpecular}
|
|
11
|
+
#import forgeax_pbr::ibl_sampling::{sampleIblDiffuse, sampleIblSpecular, sampleReflectionProbeSpecular}
|
|
6
12
|
#import forgeax_pbr::lighting_probe::{evaluateProbeDiffuse}
|
|
7
13
|
#import forgeax_pbr::tbn::{decodeTangentSpaceNormalRg, scaleTangentSpaceNormal, applyTBN}
|
|
14
|
+
#ifdef CLEARCOAT_AVAILABLE
|
|
15
|
+
#import forgeax_pbr::clearcoat::{evaluateClearcoatLayer}
|
|
16
|
+
#endif
|
|
17
|
+
#ifdef ANISOTROPY_AVAILABLE
|
|
18
|
+
#import forgeax_pbr::anisotropy::{evaluateAnisotropicNormal}
|
|
19
|
+
#endif
|
|
20
|
+
#ifdef SHEEN_AVAILABLE
|
|
21
|
+
#import forgeax_pbr::sheen::{evaluateSheenLayer}
|
|
22
|
+
#endif
|
|
23
|
+
#ifdef IRIDESCENCE_AVAILABLE
|
|
24
|
+
#import forgeax_pbr::iridescence::{evaluateIridescenceFresnel}
|
|
25
|
+
#endif
|
|
8
26
|
#import forgeax_pbr::lighting_directional::{evalDirectionalNoShadow, evalDirectionalShadowFactor}
|
|
9
27
|
#ifdef CLUSTER_FORWARD_AVAILABLE
|
|
10
|
-
#import forgeax_standard::cluster::{evaluateStandardClusterLights}
|
|
28
|
+
#import forgeax_standard::cluster::{evaluateStandardClusterLights, get_ssao_intensity}
|
|
11
29
|
#endif
|
|
12
30
|
|
|
13
31
|
#define_import_path forgeax_material::pbr-skin
|
|
@@ -16,9 +34,23 @@
|
|
|
16
34
|
#pragma variant_axis VERTEX_COLOR_AVAILABLE
|
|
17
35
|
#pragma variant_axis PROBE_BLEND_AVAILABLE
|
|
18
36
|
#pragma variant_axis EXTENDED_LIGHTING_AVAILABLE
|
|
19
|
-
|
|
37
|
+
#pragma variant_axis TRANSMISSION_AVAILABLE
|
|
20
38
|
#pragma variant_axis DIRECTIONAL_PCSS_AVAILABLE
|
|
21
39
|
|
|
40
|
+
#ifdef PROBE_BLEND_AVAILABLE
|
|
41
|
+
fn composeProbeDiffuse(
|
|
42
|
+
shPreblend : array<vec4<f32>, 9>,
|
|
43
|
+
localBlendFraction : f32,
|
|
44
|
+
normal : vec3<f32>,
|
|
45
|
+
skyIrradiance : vec3<f32>,
|
|
46
|
+
kD : vec3<f32>,
|
|
47
|
+
albedo : vec3<f32>,
|
|
48
|
+
metallic : f32,
|
|
49
|
+
) -> vec3<f32> {
|
|
50
|
+
return evaluateProbeDiffuse(shPreblend, localBlendFraction, normal, skyIrradiance, kD, albedo, metallic);
|
|
51
|
+
}
|
|
52
|
+
#endif
|
|
53
|
+
|
|
22
54
|
// @forgeax/engine-shader - default-standard-pbr-skin.wgsl
|
|
23
55
|
// (feat-20260523-skin-skeleton-animation M3 / T-29).
|
|
24
56
|
//
|
|
@@ -41,7 +73,6 @@
|
|
|
41
73
|
// @group(1) @binding(4) metallicRoughnessTexture texture_2d<f32>
|
|
42
74
|
// @group(1) @binding(5) normalSampler sampler
|
|
43
75
|
// @group(1) @binding(6) normalTexture texture_2d<f32>
|
|
44
|
-
// @group(1) @binding(7) specularTintSampler + @binding(8) specularTintTexture
|
|
45
76
|
// @group(1) @binding(9..15) Skylight (irradiance / prefilter / brdfLut +
|
|
46
77
|
// samplers) + skylight uniform (intensity)
|
|
47
78
|
// @group(2) @binding(0) meshes storage (worldFromLocal mat4
|
|
@@ -71,86 +102,128 @@
|
|
|
71
102
|
// 4 joints max; weighted sum of skinned positions from the palette buffer
|
|
72
103
|
// indexed by the per-vertex skinIndex vector.
|
|
73
104
|
|
|
74
|
-
struct
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// Channel selectors (D-8): 4 independent f32 entries split out of the
|
|
79
|
-
// legacy `channelMap : vec4<u32>`. See default-standard-pbr.wgsl for
|
|
80
|
-
// the full rationale; the skin shader shares the same merged UBO shape.
|
|
81
|
-
metallicChannel : f32,
|
|
82
|
-
roughnessChannel : f32,
|
|
83
|
-
aoChannel : f32,
|
|
84
|
-
extraChannel : f32,
|
|
85
|
-
// vec3 align=16 inserts implicit padding so emissive lands at offset 48;
|
|
86
|
-
// the authored schema rounds to 112 B (matches default-standard-pbr SSOT).
|
|
87
|
-
emissive : vec3<f32>,
|
|
88
|
-
emissiveIntensity : f32,
|
|
89
|
-
occlusionStrength : f32,
|
|
90
|
-
alphaCutoff : f32,
|
|
91
|
-
clearcoat : f32,
|
|
92
|
-
clearcoatRoughness : f32,
|
|
93
|
-
specularTint : vec3<f32>,
|
|
94
|
-
normalScale : f32,
|
|
95
|
-
transmission : f32,
|
|
96
|
-
ior : f32,
|
|
97
|
-
thickness : f32,
|
|
98
|
-
attenuationColor : vec3<f32>,
|
|
99
|
-
attenuationDistance : f32,
|
|
100
|
-
baseColorTextureCoordinatesTransform : vec4<f32>,
|
|
101
|
-
baseColorTextureCoordinatesMetadata : vec4<f32>,
|
|
102
|
-
metallicRoughnessTextureCoordinatesTransform : vec4<f32>,
|
|
103
|
-
metallicRoughnessTextureCoordinatesMetadata : vec4<f32>,
|
|
104
|
-
normalTextureCoordinatesTransform : vec4<f32>,
|
|
105
|
-
normalTextureCoordinatesMetadata : vec4<f32>,
|
|
106
|
-
specularTintTextureCoordinatesTransform : vec4<f32>,
|
|
107
|
-
specularTintTextureCoordinatesMetadata : vec4<f32>,
|
|
108
|
-
emissiveTextureCoordinatesTransform : vec4<f32>,
|
|
109
|
-
emissiveTextureCoordinatesMetadata : vec4<f32>,
|
|
110
|
-
occlusionTextureCoordinatesTransform : vec4<f32>,
|
|
111
|
-
occlusionTextureCoordinatesMetadata : vec4<f32>,
|
|
112
|
-
transmissionTextureCoordinatesTransform : vec4<f32>,
|
|
113
|
-
transmissionTextureCoordinatesMetadata : vec4<f32>,
|
|
114
|
-
thicknessTextureCoordinatesTransform : vec4<f32>,
|
|
115
|
-
thicknessTextureCoordinatesMetadata : vec4<f32>,
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
@group(1) @binding(0) var<uniform> material : Material;
|
|
105
|
+
// The MaterialParameters struct and its binding-0 declaration are generated
|
|
106
|
+
// from the root ParamSchema during material composition. Keeping the ABI out
|
|
107
|
+
// of this template prevents a second handwritten interface from drifting from
|
|
108
|
+
// the runtime UBO writer.
|
|
119
109
|
@group(1) @binding(1) var baseColorSampler : sampler;
|
|
120
110
|
@group(1) @binding(2) var baseColorTexture : texture_2d<f32>;
|
|
121
111
|
@group(1) @binding(3) var metallicRoughnessSampler : sampler;
|
|
122
112
|
@group(1) @binding(4) var metallicRoughnessTexture : texture_2d<f32>;
|
|
123
113
|
@group(1) @binding(5) var normalSampler : sampler;
|
|
124
114
|
@group(1) @binding(6) var normalTexture : texture_2d<f32>;
|
|
125
|
-
@group(1) @binding(7) var specularTintSampler : sampler;
|
|
126
|
-
@group(1) @binding(8) var specularTintTexture : texture_2d<f32>;
|
|
127
115
|
@group(1) @binding(9) var emissiveSampler : sampler;
|
|
128
116
|
@group(1) @binding(10) var emissiveTexture : texture_2d<f32>;
|
|
129
117
|
@group(1) @binding(11) var occlusionSampler : sampler;
|
|
130
118
|
@group(1) @binding(12) var occlusionTexture : texture_2d<f32>;
|
|
119
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
131
120
|
@group(1) @binding(13) var transmissionSampler : sampler;
|
|
132
121
|
@group(1) @binding(14) var transmissionTexture : texture_2d<f32>;
|
|
133
122
|
@group(1) @binding(15) var thicknessSampler : sampler;
|
|
134
123
|
@group(1) @binding(16) var thicknessTexture : texture_2d<f32>;
|
|
124
|
+
@group(1) @binding(24) var transmissionBackdropSampler : sampler;
|
|
125
|
+
@group(1) @binding(25) var transmissionBackdropTexture : texture_2d<f32>;
|
|
126
|
+
#endif
|
|
127
|
+
#ifdef CLEARCOAT_TEXTURE_AVAILABLE
|
|
128
|
+
@group(1) @binding(26) var clearcoatSampler : sampler;
|
|
129
|
+
@group(1) @binding(27) var clearcoatTexture : texture_2d<f32>;
|
|
130
|
+
#endif
|
|
131
|
+
#ifdef CLEARCOAT_ROUGHNESS_TEXTURE_AVAILABLE
|
|
132
|
+
@group(1) @binding(28) var clearcoatRoughnessSampler : sampler;
|
|
133
|
+
@group(1) @binding(29) var clearcoatRoughnessTexture : texture_2d<f32>;
|
|
134
|
+
#endif
|
|
135
|
+
#ifdef CLEARCOAT_NORMAL_TEXTURE_AVAILABLE
|
|
136
|
+
@group(1) @binding(30) var clearcoatNormalSampler : sampler;
|
|
137
|
+
@group(1) @binding(31) var clearcoatNormalTexture : texture_2d<f32>;
|
|
138
|
+
#endif
|
|
139
|
+
#ifdef ANISOTROPY_TEXTURE_AVAILABLE
|
|
140
|
+
@group(1) @binding(32) var anisotropySampler : sampler;
|
|
141
|
+
@group(1) @binding(33) var anisotropyTexture : texture_2d<f32>;
|
|
142
|
+
#endif
|
|
143
|
+
#ifdef SHEEN_COLOR_TEXTURE_AVAILABLE
|
|
144
|
+
@group(1) @binding(34) var sheenColorSampler : sampler;
|
|
145
|
+
@group(1) @binding(35) var sheenColorTexture : texture_2d<f32>;
|
|
146
|
+
#endif
|
|
147
|
+
#ifdef SHEEN_ROUGHNESS_TEXTURE_AVAILABLE
|
|
148
|
+
@group(1) @binding(36) var sheenRoughnessSampler : sampler;
|
|
149
|
+
@group(1) @binding(37) var sheenRoughnessTexture : texture_2d<f32>;
|
|
150
|
+
#endif
|
|
151
|
+
#ifdef IRIDESCENCE_TEXTURE_AVAILABLE
|
|
152
|
+
@group(1) @binding(38) var iridescenceSampler : sampler;
|
|
153
|
+
@group(1) @binding(39) var iridescenceTexture : texture_2d<f32>;
|
|
154
|
+
#endif
|
|
155
|
+
#ifdef IRIDESCENCE_THICKNESS_TEXTURE_AVAILABLE
|
|
156
|
+
@group(1) @binding(40) var iridescenceThicknessSampler : sampler;
|
|
157
|
+
@group(1) @binding(41) var iridescenceThicknessTexture : texture_2d<f32>;
|
|
158
|
+
#endif
|
|
159
|
+
#ifdef SPECULAR_TEXTURE_AVAILABLE
|
|
160
|
+
@group(1) @binding(42) var specularTextureSampler : sampler;
|
|
161
|
+
@group(1) @binding(43) var specularTexture : texture_2d<f32>;
|
|
162
|
+
#endif
|
|
163
|
+
#ifdef SPECULAR_COLOR_TEXTURE_AVAILABLE
|
|
164
|
+
@group(1) @binding(44) var specularColorTextureSampler : sampler;
|
|
165
|
+
@group(1) @binding(45) var specularColorTexture : texture_2d<f32>;
|
|
166
|
+
#endif
|
|
135
167
|
|
|
136
168
|
// Preserve filtering reflection for resources passed to the shared sampler.
|
|
137
169
|
fn materialTextureFilteringWitness() {
|
|
138
170
|
let base = baseColorTexture;
|
|
139
171
|
let metallicRoughness = metallicRoughnessTexture;
|
|
140
172
|
let normal = normalTexture;
|
|
141
|
-
let specularTint = specularTintTexture;
|
|
142
173
|
let emissive = emissiveTexture;
|
|
143
174
|
let occlusion = occlusionTexture;
|
|
175
|
+
#ifdef CLEARCOAT_TEXTURE_AVAILABLE
|
|
176
|
+
let clearcoat = clearcoatTexture;
|
|
177
|
+
#endif
|
|
178
|
+
#ifdef CLEARCOAT_ROUGHNESS_TEXTURE_AVAILABLE
|
|
179
|
+
let clearcoatRoughness = clearcoatRoughnessTexture;
|
|
180
|
+
#endif
|
|
181
|
+
#ifdef CLEARCOAT_NORMAL_TEXTURE_AVAILABLE
|
|
182
|
+
let clearcoatNormal = clearcoatNormalTexture;
|
|
183
|
+
#endif
|
|
184
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
144
185
|
let transmission = transmissionTexture;
|
|
145
186
|
let thickness = thicknessTexture;
|
|
187
|
+
#endif
|
|
146
188
|
let baseWitness = textureSample(base, baseColorSampler, vec2<f32>(0.0));
|
|
147
189
|
let metallicRoughnessWitness = textureSample(metallicRoughness, metallicRoughnessSampler, vec2<f32>(0.0));
|
|
148
190
|
let normalWitness = textureSample(normal, normalSampler, vec2<f32>(0.0));
|
|
149
|
-
let specularTintWitness = textureSample(specularTint, specularTintSampler, vec2<f32>(0.0));
|
|
150
191
|
let emissiveWitness = textureSample(emissive, emissiveSampler, vec2<f32>(0.0));
|
|
151
192
|
let occlusionWitness = textureSample(occlusion, occlusionSampler, vec2<f32>(0.0));
|
|
193
|
+
#ifdef CLEARCOAT_TEXTURE_AVAILABLE
|
|
194
|
+
let clearcoatWitness = textureSample(clearcoat, clearcoatSampler, vec2<f32>(0.0));
|
|
195
|
+
#endif
|
|
196
|
+
#ifdef CLEARCOAT_ROUGHNESS_TEXTURE_AVAILABLE
|
|
197
|
+
let clearcoatRoughnessWitness = textureSample(clearcoatRoughness, clearcoatRoughnessSampler, vec2<f32>(0.0));
|
|
198
|
+
#endif
|
|
199
|
+
#ifdef CLEARCOAT_NORMAL_TEXTURE_AVAILABLE
|
|
200
|
+
let clearcoatNormalWitness = textureSample(clearcoatNormal, clearcoatNormalSampler, vec2<f32>(0.0));
|
|
201
|
+
#endif
|
|
202
|
+
#ifdef ANISOTROPY_TEXTURE_AVAILABLE
|
|
203
|
+
let anisotropyWitness = textureSample(anisotropyTexture, anisotropySampler, vec2<f32>(0.0));
|
|
204
|
+
#endif
|
|
205
|
+
#ifdef SHEEN_COLOR_TEXTURE_AVAILABLE
|
|
206
|
+
let sheenColorWitness = textureSample(sheenColorTexture, sheenColorSampler, vec2<f32>(0.0));
|
|
207
|
+
#endif
|
|
208
|
+
#ifdef SHEEN_ROUGHNESS_TEXTURE_AVAILABLE
|
|
209
|
+
let sheenRoughnessWitness = textureSample(sheenRoughnessTexture, sheenRoughnessSampler, vec2<f32>(0.0));
|
|
210
|
+
#endif
|
|
211
|
+
#ifdef IRIDESCENCE_TEXTURE_AVAILABLE
|
|
212
|
+
let iridescenceWitness = textureSample(iridescenceTexture, iridescenceSampler, vec2<f32>(0.0));
|
|
213
|
+
#endif
|
|
214
|
+
#ifdef IRIDESCENCE_THICKNESS_TEXTURE_AVAILABLE
|
|
215
|
+
let iridescenceThicknessWitness = textureSample(iridescenceThicknessTexture, iridescenceThicknessSampler, vec2<f32>(0.0));
|
|
216
|
+
#endif
|
|
217
|
+
#ifdef SPECULAR_TEXTURE_AVAILABLE
|
|
218
|
+
let specularWeightWitness = textureSample(specularTexture, specularTextureSampler, vec2<f32>(0.0));
|
|
219
|
+
#endif
|
|
220
|
+
#ifdef SPECULAR_COLOR_TEXTURE_AVAILABLE
|
|
221
|
+
let specularColorWitness = textureSample(specularColorTexture, specularColorTextureSampler, vec2<f32>(0.0));
|
|
222
|
+
#endif
|
|
223
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
152
224
|
let transmissionWitness = textureSample(transmission, transmissionSampler, vec2<f32>(0.0));
|
|
153
225
|
let thicknessWitness = textureSample(thickness, thicknessSampler, vec2<f32>(0.0));
|
|
226
|
+
#endif
|
|
154
227
|
}
|
|
155
228
|
|
|
156
229
|
struct SkylightUniforms {
|
|
@@ -176,34 +249,16 @@ struct SkylightUniforms {
|
|
|
176
249
|
@group(1) @binding(23) var<uniform> skylight : SkylightUniforms;
|
|
177
250
|
|
|
178
251
|
#ifdef PROBE_BLEND_AVAILABLE
|
|
179
|
-
// Optional consumer lane. The host must provide the retained 160B record
|
|
180
|
-
// buffer and matching BGL before enabling this capability.
|
|
181
252
|
@group(3) @binding(1) var<storage, read> probeBlendRecords : array<vec4<f32>>;
|
|
182
253
|
#endif
|
|
183
254
|
|
|
184
|
-
#
|
|
185
|
-
@group(2) @binding(1) var<storage, read>
|
|
186
|
-
@group(2) @binding(2) var<storage, read>
|
|
187
|
-
#else
|
|
188
|
-
@group(2) @binding(1) var<uniform> paletteUniform : array<mat4x4<f32>, 255>;
|
|
189
|
-
@group(2) @binding(2) var<uniform> previousPaletteUniform : array<mat4x4<f32>, 255>;
|
|
190
|
-
#endif
|
|
191
|
-
|
|
192
|
-
fn skinPalette(index : u32) -> mat4x4<f32> {
|
|
193
|
-
#ifdef STORAGE_BUFFER_AVAILABLE
|
|
194
|
-
return paletteStorage[index];
|
|
255
|
+
#if STORAGE_BUFFER_AVAILABLE == true
|
|
256
|
+
@group(2) @binding(1) var<storage, read> palette : array<mat4x4<f32>>;
|
|
257
|
+
@group(2) @binding(2) var<storage, read> previousPalette : array<mat4x4<f32>>;
|
|
195
258
|
#else
|
|
196
|
-
|
|
259
|
+
@group(2) @binding(1) var<uniform> palette : array<mat4x4<f32>, 255>;
|
|
260
|
+
@group(2) @binding(2) var<uniform> previousPalette : array<mat4x4<f32>, 255>;
|
|
197
261
|
#endif
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
fn previousSkinPalette(index : u32) -> mat4x4<f32> {
|
|
201
|
-
#ifdef STORAGE_BUFFER_AVAILABLE
|
|
202
|
-
return previousPaletteStorage[index];
|
|
203
|
-
#else
|
|
204
|
-
return previousPaletteUniform[index];
|
|
205
|
-
#endif
|
|
206
|
-
}
|
|
207
262
|
|
|
208
263
|
struct VsIn {
|
|
209
264
|
@location(0) pos : vec3<f32>,
|
|
@@ -227,6 +282,13 @@ struct VsIn {
|
|
|
227
282
|
};
|
|
228
283
|
struct VsOut {
|
|
229
284
|
@builtin(position) clip : vec4<f32>,
|
|
285
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
286
|
+
@location(4) @interpolate(flat) transmissionBasis0 : vec4<f32>,
|
|
287
|
+
#else
|
|
288
|
+
// WebGL2 exposes only inter-stage locations 0..14. Pack the object-space
|
|
289
|
+
// Surface position with its cluster/CSM depth in one varying.
|
|
290
|
+
@location(7) positionOSAndViewZ : vec4<f32>,
|
|
291
|
+
#endif
|
|
230
292
|
@location(0) worldPos : vec3<f32>,
|
|
231
293
|
@location(1) worldNormal : vec3<f32>,
|
|
232
294
|
@location(2) uv : vec2<f32>,
|
|
@@ -238,27 +300,20 @@ struct VsOut {
|
|
|
238
300
|
@location(9) uv3 : vec2<f32>,
|
|
239
301
|
@location(10) uv4 : vec2<f32>,
|
|
240
302
|
@location(11) uv5 : vec2<f32>,
|
|
241
|
-
|
|
242
|
-
|
|
303
|
+
// UV6/UV7 share one vec4 slot so the transmission basis tail can stay
|
|
304
|
+
// inside WebGL2's 14 user varying locations.
|
|
305
|
+
@location(12) uv6And7 : vec4<f32>,
|
|
243
306
|
#ifdef VERTEX_COLOR_AVAILABLE
|
|
244
307
|
@location(14) color : vec4<f32>,
|
|
245
308
|
#endif
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
@location(6) ndc : vec3<f32>,
|
|
309
|
+
@location(6) ndc : vec4<f32>,
|
|
310
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
249
311
|
@location(7) viewZ : f32,
|
|
312
|
+
@location(13) @interpolate(flat) transmissionBasis1 : vec4<f32>,
|
|
313
|
+
#endif
|
|
250
314
|
};
|
|
251
315
|
|
|
252
|
-
fn
|
|
253
|
-
switch (channelIndex) {
|
|
254
|
-
case 0u: { return rgba.r; }
|
|
255
|
-
case 1u: { return rgba.g; }
|
|
256
|
-
case 2u: { return rgba.b; }
|
|
257
|
-
default: { return rgba.a; }
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
fn vs_main_impl(in : VsIn, idx : u32) -> VsOut {
|
|
316
|
+
fn vs_main_impl(in : VsIn, meshIndex : u32, instanceIndex : u32) -> VsOut {
|
|
262
317
|
// 4-bone weighted skinning (plan-strategy D-3 / D-3a).
|
|
263
318
|
// The host pre-computes each joint matrix as worldFromJoint * inverseBindMatrix
|
|
264
319
|
// (CPU-side pre-multiplication, per D-4) and writes them into the palette
|
|
@@ -270,10 +325,10 @@ fn vs_main_impl(in : VsIn, idx : u32) -> VsOut {
|
|
|
270
325
|
// The host sets the BindGroup dynamic offset to (byteOffset / 64) so the
|
|
271
326
|
// first palette entry visible to this draw is palette[0]. The shader
|
|
272
327
|
// indexes into palette directly using the per-vertex skinIndex values.
|
|
273
|
-
let skinMatrix =
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
328
|
+
let skinMatrix = palette[in.skinIndex.x] * in.skinWeight.x +
|
|
329
|
+
palette[in.skinIndex.y] * in.skinWeight.y +
|
|
330
|
+
palette[in.skinIndex.z] * in.skinWeight.z +
|
|
331
|
+
palette[in.skinIndex.w] * in.skinWeight.w;
|
|
277
332
|
|
|
278
333
|
// glTF 2.0 sec.Skins Implementation Note: when a mesh node has a skin
|
|
279
334
|
// property, the joint matrices already encode the global transform of each
|
|
@@ -285,7 +340,7 @@ fn vs_main_impl(in : VsIn, idx : u32) -> VsOut {
|
|
|
285
340
|
// skinnedLocal IS the world position -- no additional left-multiply by
|
|
286
341
|
// meshes[0].worldFromLocal or instanceLocal is needed.
|
|
287
342
|
//
|
|
288
|
-
// This removes the implicit contract "Skin entity
|
|
343
|
+
// This removes the implicit contract "Skin entity Transform.world must be
|
|
289
344
|
// identity" -- a skin entity can be parented under any Transform chain and
|
|
290
345
|
// the skinned mesh will rigidly follow via joint propagation alone.
|
|
291
346
|
let skinnedLocal = skinMatrix * vec4<f32>(in.pos, 1.0);
|
|
@@ -307,10 +362,13 @@ fn vs_main_impl(in : VsIn, idx : u32) -> VsOut {
|
|
|
307
362
|
// globals. The host-side BGL shape must remain compatible with non-skin
|
|
308
363
|
// PBR pipeline layout (buildPbrSkinLayouts declares 2-entry mesh-array
|
|
309
364
|
// slot + separate instances slot). Without these keep-alive references,
|
|
310
|
-
// createRenderPipeline would fail
|
|
311
|
-
_ = meshes[
|
|
312
|
-
_ = instances[
|
|
365
|
+
// createRenderPipeline would fail at binding-count validation.
|
|
366
|
+
_ = meshes[meshIndex].worldFromLocal;
|
|
367
|
+
_ = instances[instanceIndex].localFromInstance;
|
|
313
368
|
out.clip = view.worldViewProj * skinnedLocal;
|
|
369
|
+
#ifndef TRANSMISSION_AVAILABLE
|
|
370
|
+
out.positionOSAndViewZ = vec4<f32>(in.pos, sceneViewZ(out.clip, view.temporalProjection));
|
|
371
|
+
#endif
|
|
314
372
|
out.worldPos = skinnedLocal.xyz;
|
|
315
373
|
out.worldNormal = normalize(skinNormal3x3 * in.normal);
|
|
316
374
|
let worldTangentXyz = normalize(skinNormal3x3 * in.tangent.xyz);
|
|
@@ -321,30 +379,46 @@ fn vs_main_impl(in : VsIn, idx : u32) -> VsOut {
|
|
|
321
379
|
out.uv3 = in.uv3;
|
|
322
380
|
out.uv4 = in.uv4;
|
|
323
381
|
out.uv5 = in.uv5;
|
|
324
|
-
out.
|
|
325
|
-
out.uv7 = in.uv7;
|
|
382
|
+
out.uv6And7 = vec4<f32>(in.uv6, in.uv7);
|
|
326
383
|
#ifdef VERTEX_COLOR_AVAILABLE
|
|
327
384
|
out.color = in.color;
|
|
328
385
|
#endif
|
|
386
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
387
|
+
// Skin palette already contains the world-space transform. Forward its
|
|
388
|
+
// affine basis so transmission does not reread Mesh/Instance storage in
|
|
389
|
+
// the fragment stage.
|
|
390
|
+
out.transmissionBasis0 = vec4<f32>(skinMatrix[0].xyz, skinMatrix[1].x);
|
|
391
|
+
out.transmissionBasis1 = vec4<f32>(skinMatrix[1].y, skinMatrix[1].z, skinMatrix[2].x, skinMatrix[2].y);
|
|
392
|
+
#endif
|
|
393
|
+
let clipPos = out.clip;
|
|
394
|
+
out.ndc = vec4(clipPos.xy / clipPos.w, clipPos.z / clipPos.w, skinMatrix[2].z);
|
|
329
395
|
// feat-20260613-csm-cascaded-shadow-maps M5 / w19: viewZ replaces the
|
|
330
396
|
// prior light-space-position varying; evalDirectional picks the cascade
|
|
331
397
|
// matrix per fragment from viewZ + worldPos.
|
|
332
|
-
let clipPos = out.clip;
|
|
333
|
-
out.ndc = vec3(clipPos.xy / clipPos.w, clipPos.z / clipPos.w);
|
|
334
398
|
// Keep the cluster depth exactly aligned with the CPU binner for both
|
|
335
399
|
// perspective and off-axis orthographic projections.
|
|
336
|
-
|
|
400
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
401
|
+
out.viewZ = sceneViewZ(clipPos, view.temporalProjection);
|
|
402
|
+
#endif
|
|
337
403
|
return out;
|
|
338
404
|
}
|
|
339
405
|
|
|
406
|
+
fn standardViewZ(in : VsOut) -> f32 {
|
|
407
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
408
|
+
return in.viewZ;
|
|
409
|
+
#else
|
|
410
|
+
return in.positionOSAndViewZ.w;
|
|
411
|
+
#endif
|
|
412
|
+
}
|
|
413
|
+
|
|
340
414
|
@vertex
|
|
341
415
|
fn vs_main(in : VsIn, @builtin(instance_index) idx : u32) -> VsOut {
|
|
342
|
-
return vs_main_impl(in, idx);
|
|
416
|
+
return vs_main_impl(in, 0u, idx);
|
|
343
417
|
}
|
|
344
418
|
|
|
345
419
|
@vertex
|
|
346
420
|
fn vs_scene_index(in : VsIn, @builtin(instance_index) idx : u32) -> VsOut {
|
|
347
|
-
return vs_main_impl(in, idx);
|
|
421
|
+
return vs_main_impl(in, idx, 0u);
|
|
348
422
|
}
|
|
349
423
|
|
|
350
424
|
fn transformedMaterialUv(transform : vec4<f32>, metadata : vec4<f32>, in : VsOut) -> vec2<f32> {
|
|
@@ -354,8 +428,8 @@ fn transformedMaterialUv(transform : vec4<f32>, metadata : vec4<f32>, in : VsOut
|
|
|
354
428
|
if (metadata.x >= 3.0) { source = in.uv3; }
|
|
355
429
|
if (metadata.x >= 4.0) { source = in.uv4; }
|
|
356
430
|
if (metadata.x >= 5.0) { source = in.uv5; }
|
|
357
|
-
if (metadata.x >= 6.0) { source = in.
|
|
358
|
-
if (metadata.x >= 7.0) { source = in.
|
|
431
|
+
if (metadata.x >= 6.0) { source = in.uv6And7.xy; }
|
|
432
|
+
if (metadata.x >= 7.0) { source = in.uv6And7.zw; }
|
|
359
433
|
let scaled = source * transform.zw;
|
|
360
434
|
let angle = metadata.y;
|
|
361
435
|
let c = cos(angle);
|
|
@@ -371,58 +445,269 @@ fn materialVertexColor(in : VsOut) -> vec4<f32> {
|
|
|
371
445
|
#endif
|
|
372
446
|
}
|
|
373
447
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
448
|
+
// Keep the cooked skinned artifact content-addressable per declared
|
|
449
|
+
// capability set, including axes whose imported helper/resource surface is
|
|
450
|
+
// otherwise identical after lowering.
|
|
451
|
+
fn standardSkinVariantIdentity() -> f32 {
|
|
452
|
+
var identity = 0.0;
|
|
453
|
+
#ifdef STORAGE_BUFFER_AVAILABLE
|
|
454
|
+
identity = identity + 1.0;
|
|
455
|
+
#endif
|
|
456
|
+
#ifdef CLUSTER_FORWARD_AVAILABLE
|
|
457
|
+
identity = identity + 2.0;
|
|
458
|
+
#endif
|
|
459
|
+
#ifdef VERTEX_COLOR_AVAILABLE
|
|
460
|
+
identity = identity + 4.0;
|
|
461
|
+
#endif
|
|
462
|
+
#ifdef PROBE_BLEND_AVAILABLE
|
|
463
|
+
identity = identity + 8.0;
|
|
464
|
+
#endif
|
|
465
|
+
#ifdef EXTENDED_LIGHTING_AVAILABLE
|
|
466
|
+
identity = identity + 16.0;
|
|
467
|
+
#endif
|
|
468
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
469
|
+
identity = identity + 32.0;
|
|
470
|
+
#endif
|
|
471
|
+
#ifdef DIRECTIONAL_PCSS_AVAILABLE
|
|
472
|
+
identity = identity + 64.0;
|
|
473
|
+
#endif
|
|
474
|
+
return identity;
|
|
475
|
+
}
|
|
384
476
|
|
|
385
|
-
|
|
386
|
-
let
|
|
387
|
-
|
|
388
|
-
let
|
|
477
|
+
fn evaluateStandardSurface(in : VsOut, frontFacing : bool) -> SurfaceData {
|
|
478
|
+
let viewDirectionWS = normalize(view.cameraPos - in.worldPos);
|
|
479
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
480
|
+
let positionOS = in.worldPos;
|
|
481
|
+
#else
|
|
482
|
+
let positionOS = in.positionOSAndViewZ.xyz;
|
|
483
|
+
#endif
|
|
484
|
+
return evaluate_surface(SurfaceInput(
|
|
485
|
+
positionOS,
|
|
486
|
+
in.worldPos,
|
|
487
|
+
in.worldNormal,
|
|
488
|
+
in.worldTangent,
|
|
489
|
+
viewDirectionWS,
|
|
490
|
+
in.uv,
|
|
491
|
+
in.uv1,
|
|
492
|
+
materialVertexColor(in),
|
|
493
|
+
frontFacing,
|
|
494
|
+
));
|
|
495
|
+
}
|
|
389
496
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
497
|
+
fn finiteScalar(value : f32, fallback : f32) -> f32 {
|
|
498
|
+
let bounded = clamp(value, -65504.0, 65504.0);
|
|
499
|
+
return select(fallback, bounded, value == value);
|
|
500
|
+
}
|
|
393
501
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
502
|
+
fn finiteColor(value : vec3<f32>, fallback : vec3<f32>) -> vec3<f32> {
|
|
503
|
+
return vec3<f32>(
|
|
504
|
+
finiteScalar(value.x, fallback.x),
|
|
505
|
+
finiteScalar(value.y, fallback.y),
|
|
506
|
+
finiteScalar(value.z, fallback.z),
|
|
398
507
|
);
|
|
399
|
-
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
fn alphaTestSurface(surface : SurfaceData) {
|
|
511
|
+
if (surface.alphaClipThreshold > 0.0 && surface.opacity <= surface.alphaClipThreshold) {
|
|
512
|
+
discard;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
@fragment
|
|
517
|
+
fn fs_main(in : VsOut, @builtin(front_facing) frontFacing : bool) -> @location(0) vec4<f32> {
|
|
518
|
+
let _variantIdentity = standardSkinVariantIdentity();
|
|
519
|
+
let surface = evaluateStandardSurface(in, frontFacing);
|
|
520
|
+
alphaTestSurface(surface);
|
|
521
|
+
let alpha = surface.opacity;
|
|
522
|
+
let albedo = surface.baseColor;
|
|
523
|
+
let metallic = clamp(finiteScalar(surface.metallic, 0.0), 0.0, 1.0);
|
|
524
|
+
let iblRoughness = clamp(finiteScalar(surface.roughness, 0.5), 0.04, 1.0);
|
|
525
|
+
let a = iblRoughness * iblRoughness;
|
|
526
|
+
let n = normalize(surface.normalWS);
|
|
400
527
|
|
|
401
528
|
let v = normalize(view.cameraPos - in.worldPos);
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
529
|
+
var specularColor = material.specularColor;
|
|
530
|
+
#ifdef SPECULAR_COLOR_TEXTURE_AVAILABLE
|
|
531
|
+
specularColor = specularColor * sampleMaterialTexture(
|
|
532
|
+
specularColorTexture,
|
|
533
|
+
specularColorTextureSampler,
|
|
534
|
+
transformedMaterialUv(
|
|
535
|
+
material.specularColorTextureCoordinatesTransform,
|
|
536
|
+
material.specularColorTextureCoordinatesMetadata,
|
|
537
|
+
in,
|
|
538
|
+
),
|
|
539
|
+
material.specularColorTextureCoordinatesMetadata.zw,
|
|
406
540
|
).rgb;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
let
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
541
|
+
#endif
|
|
542
|
+
var specularWeight = clamp(finiteScalar(material.specular, 1.0), 0.0, 1.0);
|
|
543
|
+
#ifdef SPECULAR_TEXTURE_AVAILABLE
|
|
544
|
+
let specularWeightUv = transformedMaterialUv(
|
|
545
|
+
material.specularTextureCoordinatesTransform,
|
|
546
|
+
material.specularTextureCoordinatesMetadata,
|
|
547
|
+
in,
|
|
548
|
+
);
|
|
549
|
+
specularWeight = specularWeight * sampleMaterialTexture(
|
|
550
|
+
specularTexture,
|
|
551
|
+
specularTextureSampler,
|
|
552
|
+
specularWeightUv,
|
|
553
|
+
material.specularTextureCoordinatesMetadata.zw,
|
|
554
|
+
).a;
|
|
555
|
+
#endif
|
|
556
|
+
let safeIor = max(finiteScalar(material.ior, 1.5), 1.0);
|
|
557
|
+
let dielectricF0 = pow((safeIor - 1.0) / (safeIor + 1.0), 2.0);
|
|
558
|
+
var f0 = mix(vec3<f32>(dielectricF0) * specularColor * specularWeight, albedo, metallic);
|
|
559
|
+
var physicalNormal = n;
|
|
560
|
+
#ifdef ANISOTROPY_AVAILABLE
|
|
561
|
+
var anisotropyStrength = finiteScalar(material.anisotropyStrength, 0.0);
|
|
562
|
+
var anisotropyRotation = finiteScalar(material.anisotropyRotation, 0.0);
|
|
563
|
+
var anisotropyDirection = vec2<f32>(1.0, 0.0);
|
|
564
|
+
#ifdef ANISOTROPY_TEXTURE_AVAILABLE
|
|
565
|
+
let anisotropyUv = transformedMaterialUv(
|
|
566
|
+
material.anisotropyTextureCoordinatesTransform,
|
|
567
|
+
material.anisotropyTextureCoordinatesMetadata,
|
|
568
|
+
in,
|
|
569
|
+
);
|
|
570
|
+
let anisotropySample = sampleMaterialTexture(
|
|
571
|
+
anisotropyTexture,
|
|
572
|
+
anisotropySampler,
|
|
573
|
+
anisotropyUv,
|
|
574
|
+
material.anisotropyTextureCoordinatesMetadata.zw,
|
|
575
|
+
);
|
|
576
|
+
let encodedAnisotropyDirection = 2.0 * anisotropySample.rg - vec2<f32>(1.0, 1.0);
|
|
577
|
+
if (dot(encodedAnisotropyDirection, encodedAnisotropyDirection) >= 1e-6) {
|
|
578
|
+
anisotropyDirection = normalize(encodedAnisotropyDirection);
|
|
579
|
+
}
|
|
580
|
+
anisotropyStrength = anisotropyStrength * anisotropySample.b;
|
|
581
|
+
#endif
|
|
582
|
+
physicalNormal = evaluateAnisotropicNormal(
|
|
583
|
+
n,
|
|
584
|
+
in.worldTangent,
|
|
585
|
+
anisotropyStrength,
|
|
586
|
+
anisotropyRotation,
|
|
587
|
+
anisotropyDirection,
|
|
588
|
+
);
|
|
589
|
+
#endif
|
|
590
|
+
#ifdef IRIDESCENCE_AVAILABLE
|
|
591
|
+
var iridescenceStrength = finiteScalar(material.iridescence, 0.0);
|
|
592
|
+
var iridescenceThicknessFactor = 1.0;
|
|
593
|
+
#ifdef IRIDESCENCE_TEXTURE_AVAILABLE
|
|
594
|
+
let iridescenceUv = transformedMaterialUv(
|
|
595
|
+
material.iridescenceTextureCoordinatesTransform,
|
|
596
|
+
material.iridescenceTextureCoordinatesMetadata,
|
|
597
|
+
in,
|
|
598
|
+
);
|
|
599
|
+
let iridescenceSample = sampleMaterialTexture(
|
|
600
|
+
iridescenceTexture,
|
|
601
|
+
iridescenceSampler,
|
|
602
|
+
iridescenceUv,
|
|
603
|
+
material.iridescenceTextureCoordinatesMetadata.zw,
|
|
604
|
+
);
|
|
605
|
+
iridescenceStrength = iridescenceStrength * iridescenceSample.r;
|
|
606
|
+
#endif
|
|
607
|
+
#ifdef IRIDESCENCE_THICKNESS_TEXTURE_AVAILABLE
|
|
608
|
+
let iridescenceThicknessUv = transformedMaterialUv(
|
|
609
|
+
material.iridescenceThicknessTextureCoordinatesTransform,
|
|
610
|
+
material.iridescenceThicknessTextureCoordinatesMetadata,
|
|
611
|
+
in,
|
|
612
|
+
);
|
|
613
|
+
let iridescenceThicknessSample = sampleMaterialTexture(
|
|
614
|
+
iridescenceThicknessTexture,
|
|
615
|
+
iridescenceThicknessSampler,
|
|
616
|
+
iridescenceThicknessUv,
|
|
617
|
+
material.iridescenceThicknessTextureCoordinatesMetadata.zw,
|
|
419
618
|
);
|
|
619
|
+
iridescenceThicknessFactor = clamp(iridescenceThicknessSample.g, 0.0, 1.0);
|
|
620
|
+
#endif
|
|
621
|
+
let filmThickness = mix(
|
|
622
|
+
finiteScalar(material.iridescenceThicknessMinimum, 100.0),
|
|
623
|
+
finiteScalar(material.iridescenceThicknessMaximum, 400.0),
|
|
624
|
+
iridescenceThicknessFactor,
|
|
625
|
+
);
|
|
626
|
+
f0 = evaluateIridescenceFresnel(
|
|
627
|
+
f0,
|
|
628
|
+
iridescenceStrength,
|
|
629
|
+
finiteScalar(material.iridescenceIor, 1.3),
|
|
630
|
+
filmThickness,
|
|
631
|
+
);
|
|
632
|
+
#endif
|
|
633
|
+
var diffuseAlbedo = albedo;
|
|
634
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
635
|
+
let transmissionUv = transformedMaterialUv(
|
|
636
|
+
material.transmissionTextureCoordinatesTransform,
|
|
637
|
+
material.transmissionTextureCoordinatesMetadata,
|
|
638
|
+
in,
|
|
639
|
+
);
|
|
640
|
+
let thicknessUv = transformedMaterialUv(
|
|
641
|
+
material.thicknessTextureCoordinatesTransform,
|
|
642
|
+
material.thicknessTextureCoordinatesMetadata,
|
|
643
|
+
in,
|
|
644
|
+
);
|
|
645
|
+
let transmissionSample = sampleMaterialTexture(
|
|
646
|
+
transmissionTexture,
|
|
647
|
+
transmissionSampler,
|
|
648
|
+
transmissionUv,
|
|
649
|
+
material.transmissionTextureCoordinatesMetadata.zw,
|
|
650
|
+
).r;
|
|
651
|
+
let thicknessSample = sampleMaterialTexture(
|
|
652
|
+
thicknessTexture,
|
|
653
|
+
thicknessSampler,
|
|
654
|
+
thicknessUv,
|
|
655
|
+
material.thicknessTextureCoordinatesMetadata.zw,
|
|
656
|
+
).g;
|
|
657
|
+
let transmissionFactor = clamp(
|
|
658
|
+
finiteScalar(material.transmission, 0.0) * finiteScalar(transmissionSample, 1.0),
|
|
659
|
+
0.0,
|
|
660
|
+
1.0,
|
|
661
|
+
);
|
|
662
|
+
let viewDot = finiteScalar(dot(n, v), 0.0);
|
|
663
|
+
let refractionFromInside = viewDot < 0.0;
|
|
664
|
+
let refractionNormal = select(n, -n, refractionFromInside);
|
|
665
|
+
let refractionEta = select(1.0 / safeIor, safeIor, refractionFromInside);
|
|
666
|
+
let incident = -v;
|
|
667
|
+
let refracted = refract(incident, refractionNormal, refractionEta);
|
|
668
|
+
let refractedLengthSquared = dot(refracted, refracted);
|
|
669
|
+
let viewCos = clamp(abs(viewDot), 0.0, 1.0);
|
|
670
|
+
let fresnel = clamp(f_schlick(viewCos, vec3<f32>(dielectricF0)).x, 0.0, 1.0);
|
|
671
|
+
let transmittedEnergy = select(
|
|
672
|
+
0.0,
|
|
673
|
+
transmissionFactor * (1.0 - metallic) * (1.0 - fresnel),
|
|
674
|
+
refractedLengthSquared > 1e-6,
|
|
675
|
+
);
|
|
676
|
+
diffuseAlbedo = albedo * (1.0 - transmittedEnergy);
|
|
677
|
+
#endif
|
|
678
|
+
let kD = (vec3<f32>(1.0) - f_schlick(max(dot(physicalNormal, v), 0.0), f0)) * (1.0 - metallic);
|
|
679
|
+
var coatRoughness = 0.04;
|
|
680
|
+
var coatAlpha = coatRoughness * coatRoughness;
|
|
681
|
+
var coatF = vec3<f32>(0.0);
|
|
682
|
+
#ifdef CLEARCOAT_AVAILABLE
|
|
683
|
+
coatRoughness = max(finiteScalar(material.clearcoatRoughness, 0.04), 0.04);
|
|
684
|
+
coatAlpha = coatRoughness * coatRoughness;
|
|
685
|
+
coatF = f_schlick(max(dot(physicalNormal, v), 0.0), vec3<f32>(0.04)) *
|
|
686
|
+
clamp(finiteScalar(material.clearcoat, 0.0), 0.0, 1.0);
|
|
687
|
+
#endif
|
|
688
|
+
var irradiance = vec3<f32>(0.0);
|
|
689
|
+
var specularIbl = vec3<f32>(0.0);
|
|
690
|
+
if (skylight.intensity < 0.0) {
|
|
691
|
+
specularIbl = sampleReflectionProbeSpecular(
|
|
692
|
+
physicalNormal, v, iblRoughness, f0, in.worldPos,
|
|
693
|
+
vec3<f32>(skylight.colorR, skylight.colorG, skylight.colorB),
|
|
694
|
+
skylight.rotation.xyz, vec4<f32>(0.0, 0.0, 0.0, 1.0),
|
|
695
|
+
prefilterMap, prefilterSampler, brdfLut, brdfLutSampler,
|
|
696
|
+
);
|
|
697
|
+
} else {
|
|
698
|
+
irradiance = sampleIblDiffuse(physicalNormal, skylight.rotation, irradianceMap, irradianceSampler);
|
|
699
|
+
specularIbl = sampleIblSpecular(
|
|
700
|
+
physicalNormal, v, iblRoughness, f0,
|
|
701
|
+
skylight.rotation,
|
|
702
|
+
prefilterMap, prefilterSampler, brdfLut, brdfLutSampler,
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
let ao = surface.occlusion;
|
|
420
706
|
let skyColor = vec3<f32>(skylight.colorR, skylight.colorG, skylight.colorB);
|
|
421
707
|
let skyFactor = skyColor * skylight.intensity;
|
|
422
|
-
var ambient = (kD * irradiance *
|
|
708
|
+
var ambient = (kD * irradiance * diffuseAlbedo + specularIbl) *
|
|
709
|
+
(vec3<f32>(1.0) - coatF);
|
|
423
710
|
#ifdef PROBE_BLEND_AVAILABLE
|
|
424
|
-
// group(3) is the per-object bind group; record zero is the object selected
|
|
425
|
-
// by this draw, independent of instance count.
|
|
426
711
|
let probeShPreblend = array<vec4<f32>, 9>(
|
|
427
712
|
probeBlendRecords[1], probeBlendRecords[2], probeBlendRecords[3],
|
|
428
713
|
probeBlendRecords[4], probeBlendRecords[5], probeBlendRecords[6],
|
|
@@ -430,46 +715,278 @@ fn fs_main(in : VsOut) -> @location(0) vec4<f32> {
|
|
|
430
715
|
);
|
|
431
716
|
let probeLocalBlendFraction = probeBlendRecords[0].z;
|
|
432
717
|
let probeDiffuseK = kD / max(vec3<f32>(1.0 - metallic), vec3<f32>(0.0001));
|
|
433
|
-
let probeDiffuse =
|
|
434
|
-
|
|
718
|
+
let probeDiffuse = composeProbeDiffuse(probeShPreblend,
|
|
719
|
+
probeLocalBlendFraction,
|
|
720
|
+
physicalNormal,
|
|
721
|
+
irradiance * skyFactor,
|
|
722
|
+
probeDiffuseK,
|
|
723
|
+
diffuseAlbedo,
|
|
724
|
+
metallic,
|
|
725
|
+
);
|
|
726
|
+
ambient = (probeDiffuse + specularIbl * skyFactor) *
|
|
727
|
+
(vec3<f32>(1.0) - coatF);
|
|
435
728
|
#endif
|
|
436
|
-
if (material.clearcoat != 0.0) {
|
|
437
|
-
let clearcoatIbl = sampleIblSpecular(
|
|
438
|
-
n, v, coatRoughness, vec3<f32>(0.04),
|
|
439
|
-
skylight.rotation,
|
|
440
|
-
prefilterMap, prefilterSampler, brdfLut, brdfLutSampler,
|
|
441
|
-
);
|
|
442
|
-
ambient = ambient + clearcoatIbl * material.clearcoat * skyFactor;
|
|
443
|
-
}
|
|
444
729
|
#ifdef PROBE_BLEND_AVAILABLE
|
|
445
|
-
ambient = ambient;
|
|
730
|
+
ambient = ambient * ao;
|
|
446
731
|
#else
|
|
447
|
-
|
|
732
|
+
if (skylight.intensity < 0.0) {
|
|
733
|
+
let environmentScale = max(-skylight.intensity - 1.0, 0.0) * ao;
|
|
734
|
+
ambient = ambient * environmentScale;
|
|
735
|
+
} else {
|
|
736
|
+
let environmentScale = skyColor * skylight.intensity * ao;
|
|
737
|
+
ambient = ambient * environmentScale;
|
|
738
|
+
}
|
|
448
739
|
#endif
|
|
449
740
|
var color = ambient;
|
|
450
|
-
|
|
451
|
-
let
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
741
|
+
#ifdef TRANSMISSION_AVAILABLE
|
|
742
|
+
let screenUv = in.ndc.xy * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);
|
|
743
|
+
let localToWorld0 = in.transmissionBasis0.xyz;
|
|
744
|
+
let localToWorld1 = vec3<f32>(
|
|
745
|
+
in.transmissionBasis0.w,
|
|
746
|
+
in.transmissionBasis1.x,
|
|
747
|
+
in.transmissionBasis1.y,
|
|
748
|
+
);
|
|
749
|
+
let localToWorld2 = vec3<f32>(
|
|
750
|
+
in.transmissionBasis1.z,
|
|
751
|
+
in.transmissionBasis1.w,
|
|
752
|
+
in.ndc.w,
|
|
753
|
+
);
|
|
754
|
+
let inverseCofactor0 = cross(localToWorld1, localToWorld2);
|
|
755
|
+
let inverseCofactor1 = cross(localToWorld2, localToWorld0);
|
|
756
|
+
let inverseCofactor2 = cross(localToWorld0, localToWorld1);
|
|
757
|
+
let localToWorldDet = dot(localToWorld0, inverseCofactor0);
|
|
758
|
+
let safeLocalToWorldDet = select(1.0, localToWorldDet, abs(localToWorldDet) >= 1e-6);
|
|
759
|
+
let worldToLocal0 = vec3<f32>(
|
|
760
|
+
inverseCofactor0.x,
|
|
761
|
+
inverseCofactor1.x,
|
|
762
|
+
inverseCofactor2.x,
|
|
763
|
+
) / safeLocalToWorldDet;
|
|
764
|
+
let worldToLocal1 = vec3<f32>(
|
|
765
|
+
inverseCofactor0.y,
|
|
766
|
+
inverseCofactor1.y,
|
|
767
|
+
inverseCofactor2.y,
|
|
768
|
+
) / safeLocalToWorldDet;
|
|
769
|
+
let worldToLocal2 = vec3<f32>(
|
|
770
|
+
inverseCofactor0.z,
|
|
771
|
+
inverseCofactor1.z,
|
|
772
|
+
inverseCofactor2.z,
|
|
773
|
+
) / safeLocalToWorldDet;
|
|
774
|
+
let refractedLocal = normalize(
|
|
775
|
+
worldToLocal0 * refracted.x +
|
|
776
|
+
worldToLocal1 * refracted.y +
|
|
777
|
+
worldToLocal2 * refracted.z,
|
|
778
|
+
);
|
|
779
|
+
let worldRefractedDirection =
|
|
780
|
+
localToWorld0 * refractedLocal.x +
|
|
781
|
+
localToWorld1 * refractedLocal.y +
|
|
782
|
+
localToWorld2 * refractedLocal.z;
|
|
783
|
+
let worldThickness = max(
|
|
784
|
+
finiteScalar(material.thickness, 0.0) * length(worldRefractedDirection) *
|
|
785
|
+
finiteScalar(thicknessSample, 1.0),
|
|
786
|
+
0.0,
|
|
787
|
+
);
|
|
788
|
+
let refractedUv = screenUv + (refracted.xy - incident.xy) * worldThickness * 0.25;
|
|
789
|
+
let guardBand = 0.02;
|
|
790
|
+
let insideGuardBand = all(refractedUv >= vec2<f32>(guardBand)) &&
|
|
791
|
+
all(refractedUv <= vec2<f32>(1.0 - guardBand));
|
|
792
|
+
let backdropMipCount = textureNumLevels(transmissionBackdropTexture);
|
|
793
|
+
let backdropMaxLod = max(f32(backdropMipCount) - 1.0, 0.0);
|
|
794
|
+
let backdropLod = clamp(iblRoughness * iblRoughness * backdropMaxLod, 0.0, backdropMaxLod);
|
|
795
|
+
let unrefractedBackdrop = textureSampleLevel(
|
|
796
|
+
transmissionBackdropTexture,
|
|
797
|
+
transmissionBackdropSampler,
|
|
798
|
+
clamp(screenUv, vec2<f32>(0.0), vec2<f32>(1.0)),
|
|
799
|
+
backdropLod,
|
|
800
|
+
).rgb;
|
|
801
|
+
var transmittedBackdrop = unrefractedBackdrop;
|
|
802
|
+
if (refractedLengthSquared > 1e-6 && insideGuardBand) {
|
|
803
|
+
transmittedBackdrop = textureSampleLevel(
|
|
804
|
+
transmissionBackdropTexture,
|
|
805
|
+
transmissionBackdropSampler,
|
|
806
|
+
clamp(refractedUv, vec2<f32>(0.0), vec2<f32>(1.0)),
|
|
807
|
+
backdropLod,
|
|
808
|
+
).rgb;
|
|
458
809
|
}
|
|
810
|
+
let safeAttenuationColor = clamp(
|
|
811
|
+
finiteColor(material.attenuationColor, vec3<f32>(1.0)),
|
|
812
|
+
vec3<f32>(0.0),
|
|
813
|
+
vec3<f32>(1.0),
|
|
814
|
+
);
|
|
815
|
+
let safeAttenuationDistance = max(finiteScalar(material.attenuationDistance, 0.0), 0.0);
|
|
816
|
+
let attenuationExponent = worldThickness / max(safeAttenuationDistance, 1e-6);
|
|
817
|
+
let beerAttenuation = select(
|
|
818
|
+
vec3<f32>(1.0),
|
|
819
|
+
pow(safeAttenuationColor, vec3<f32>(attenuationExponent)),
|
|
820
|
+
safeAttenuationDistance > 1e-6 && worldThickness > 0.0,
|
|
821
|
+
);
|
|
822
|
+
color = color + finiteColor(transmittedBackdrop, vec3<f32>(0.0)) *
|
|
823
|
+
transmittedEnergy * beerAttenuation;
|
|
824
|
+
#endif
|
|
825
|
+
color = color + surface.emissive;
|
|
826
|
+
let directionalShadow = evalDirectionalShadowFactor(
|
|
827
|
+
physicalNormal,
|
|
828
|
+
in.worldPos,
|
|
829
|
+
standardViewZ(in),
|
|
830
|
+
);
|
|
831
|
+
let directionalBase = evalDirectionalNoShadow(physicalNormal, v, diffuseAlbedo, metallic, a, f0);
|
|
832
|
+
color = color + directionalShadow * directionalBase;
|
|
459
833
|
#ifdef CLUSTER_FORWARD_AVAILABLE
|
|
460
834
|
color = color + evaluateStandardClusterLights(
|
|
461
|
-
in.ndc, in
|
|
835
|
+
in.ndc.xyz, standardViewZ(in), in.worldPos, physicalNormal, v,
|
|
836
|
+
diffuseAlbedo, metallic, a, f0, false,
|
|
837
|
+
);
|
|
838
|
+
#endif // CLUSTER_FORWARD_AVAILABLE
|
|
839
|
+
#ifdef SHEEN_AVAILABLE
|
|
840
|
+
var sheenColor = material.sheenColor;
|
|
841
|
+
var sheenRoughnessFactor = 1.0;
|
|
842
|
+
#ifdef SHEEN_COLOR_TEXTURE_AVAILABLE
|
|
843
|
+
sheenColor = sheenColor * sampleMaterialTexture(
|
|
844
|
+
sheenColorTexture,
|
|
845
|
+
sheenColorSampler,
|
|
846
|
+
transformedMaterialUv(material.sheenColorTextureCoordinatesTransform, material.sheenColorTextureCoordinatesMetadata, in),
|
|
847
|
+
material.sheenColorTextureCoordinatesMetadata.zw,
|
|
848
|
+
).rgb;
|
|
849
|
+
#endif
|
|
850
|
+
#ifdef SHEEN_ROUGHNESS_TEXTURE_AVAILABLE
|
|
851
|
+
sheenRoughnessFactor = sampleMaterialTexture(
|
|
852
|
+
sheenRoughnessTexture,
|
|
853
|
+
sheenRoughnessSampler,
|
|
854
|
+
transformedMaterialUv(material.sheenRoughnessTextureCoordinatesTransform, material.sheenRoughnessTextureCoordinatesMetadata, in),
|
|
855
|
+
material.sheenRoughnessTextureCoordinatesMetadata.zw,
|
|
856
|
+
).a;
|
|
857
|
+
#endif
|
|
858
|
+
let sheenRoughness = clamp(
|
|
859
|
+
material.sheenRoughness * sheenRoughnessFactor,
|
|
860
|
+
0.0,
|
|
861
|
+
1.0,
|
|
862
|
+
);
|
|
863
|
+
color = evaluateSheenLayer(color, sheenColor, sheenRoughness, dot(n, v));
|
|
864
|
+
#endif
|
|
865
|
+
#ifdef CLEARCOAT_AVAILABLE
|
|
866
|
+
var clearcoatFactor = clamp(material.clearcoat, 0.0, 1.0);
|
|
867
|
+
#ifdef CLEARCOAT_TEXTURE_AVAILABLE
|
|
868
|
+
let clearcoatUv = transformedMaterialUv(material.clearcoatTextureCoordinatesTransform, material.clearcoatTextureCoordinatesMetadata, in);
|
|
869
|
+
clearcoatFactor = clamp(
|
|
870
|
+
material.clearcoat * sampleMaterialTexture(
|
|
871
|
+
clearcoatTexture,
|
|
872
|
+
clearcoatSampler,
|
|
873
|
+
clearcoatUv,
|
|
874
|
+
material.clearcoatTextureCoordinatesMetadata.zw,
|
|
875
|
+
).r,
|
|
876
|
+
0.0,
|
|
877
|
+
1.0,
|
|
878
|
+
);
|
|
879
|
+
#endif
|
|
880
|
+
var clearcoatRoughnessValue = clamp(max(material.clearcoatRoughness, 0.04), 0.04, 1.0);
|
|
881
|
+
#ifdef CLEARCOAT_ROUGHNESS_TEXTURE_AVAILABLE
|
|
882
|
+
let clearcoatRoughnessUv = transformedMaterialUv(material.clearcoatRoughnessTextureCoordinatesTransform, material.clearcoatRoughnessTextureCoordinatesMetadata, in);
|
|
883
|
+
clearcoatRoughnessValue = clamp(
|
|
884
|
+
max(material.clearcoatRoughness, 0.04) * sampleMaterialTexture(
|
|
885
|
+
clearcoatRoughnessTexture,
|
|
886
|
+
clearcoatRoughnessSampler,
|
|
887
|
+
clearcoatRoughnessUv,
|
|
888
|
+
material.clearcoatRoughnessTextureCoordinatesMetadata.zw,
|
|
889
|
+
).g,
|
|
890
|
+
0.04,
|
|
891
|
+
1.0,
|
|
462
892
|
);
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
893
|
+
#endif
|
|
894
|
+
var clearcoatNormalValue = in.worldNormal;
|
|
895
|
+
#ifdef CLEARCOAT_NORMAL_TEXTURE_AVAILABLE
|
|
896
|
+
let clearcoatNormalUv = transformedMaterialUv(material.clearcoatNormalTextureCoordinatesTransform, material.clearcoatNormalTextureCoordinatesMetadata, in);
|
|
897
|
+
clearcoatNormalValue = applyTBN(
|
|
898
|
+
in.worldNormal,
|
|
899
|
+
in.worldTangent,
|
|
900
|
+
scaleTangentSpaceNormal(
|
|
901
|
+
decodeTangentSpaceNormalRg(sampleMaterialTexture(
|
|
902
|
+
clearcoatNormalTexture,
|
|
903
|
+
clearcoatNormalSampler,
|
|
904
|
+
clearcoatNormalUv,
|
|
905
|
+
material.clearcoatNormalTextureCoordinatesMetadata.zw,
|
|
906
|
+
).rg),
|
|
907
|
+
material.clearcoatNormalScale,
|
|
908
|
+
),
|
|
909
|
+
);
|
|
910
|
+
#endif
|
|
911
|
+
var clearcoatIbl = vec3<f32>(0.0);
|
|
912
|
+
if (skylight.intensity < 0.0) {
|
|
913
|
+
clearcoatIbl = sampleReflectionProbeSpecular(
|
|
914
|
+
clearcoatNormalValue,
|
|
915
|
+
v,
|
|
916
|
+
clearcoatRoughnessValue,
|
|
917
|
+
vec3<f32>(0.04),
|
|
918
|
+
in.worldPos,
|
|
919
|
+
vec3<f32>(skylight.colorR, skylight.colorG, skylight.colorB),
|
|
920
|
+
skylight.rotation.xyz,
|
|
921
|
+
vec4<f32>(0.0, 0.0, 0.0, 1.0),
|
|
922
|
+
prefilterMap,
|
|
923
|
+
prefilterSampler,
|
|
924
|
+
brdfLut,
|
|
925
|
+
brdfLutSampler,
|
|
926
|
+
);
|
|
927
|
+
} else {
|
|
928
|
+
clearcoatIbl = sampleIblSpecular(
|
|
929
|
+
clearcoatNormalValue,
|
|
930
|
+
v,
|
|
931
|
+
clearcoatRoughnessValue,
|
|
932
|
+
vec3<f32>(0.04),
|
|
933
|
+
skylight.rotation,
|
|
934
|
+
prefilterMap,
|
|
935
|
+
prefilterSampler,
|
|
936
|
+
brdfLut,
|
|
937
|
+
brdfLutSampler,
|
|
467
938
|
);
|
|
468
939
|
}
|
|
940
|
+
let clearcoatAlpha = clearcoatRoughnessValue * clearcoatRoughnessValue;
|
|
941
|
+
let clearcoatDirect = directionalShadow * evalDirectionalNoShadow(
|
|
942
|
+
clearcoatNormalValue,
|
|
943
|
+
v,
|
|
944
|
+
vec3<f32>(0.0),
|
|
945
|
+
1.0,
|
|
946
|
+
clearcoatAlpha,
|
|
947
|
+
vec3<f32>(0.04),
|
|
948
|
+
);
|
|
949
|
+
let directionalClearcoat = clearcoatDirect;
|
|
950
|
+
var clearcoatEnvironment = clearcoatIbl * skyColor * skylight.intensity;
|
|
951
|
+
if (skylight.intensity < 0.0) {
|
|
952
|
+
clearcoatEnvironment = clearcoatIbl;
|
|
953
|
+
}
|
|
954
|
+
color = evaluateClearcoatLayer(
|
|
955
|
+
color,
|
|
956
|
+
clearcoatEnvironment + directionalClearcoat,
|
|
957
|
+
dot(clearcoatNormalValue, v),
|
|
958
|
+
clearcoatFactor,
|
|
959
|
+
);
|
|
469
960
|
#endif
|
|
470
961
|
return vec4<f32>(color, alpha);
|
|
471
962
|
}
|
|
472
963
|
|
|
964
|
+
// Keep the skinned Standard shader on the same multi-entry pass contract as
|
|
965
|
+
// the rigid Standard shader. Deferred draws select this entry point from the
|
|
966
|
+
// existing `forgeax::pbr-skin` artifact; lighting is performed by the deferred
|
|
967
|
+
// pass after these base surface facts are written to the shared G-buffer.
|
|
968
|
+
struct GBufferOutput {
|
|
969
|
+
@location(0) normal_roughness : vec4<f32>,
|
|
970
|
+
@location(1) albedo_metallic : vec4<f32>,
|
|
971
|
+
@location(2) emissive_ao : vec4<f32>,
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
@fragment
|
|
975
|
+
fn fs_gbuffer(in : VsOut, @builtin(front_facing) frontFacing : bool) -> GBufferOutput {
|
|
976
|
+
let surface = evaluateStandardSurface(in, frontFacing);
|
|
977
|
+
alphaTestSurface(surface);
|
|
978
|
+
let albedo = surface.baseColor;
|
|
979
|
+
let metallic = clamp(surface.metallic, 0.0, 1.0);
|
|
980
|
+
let roughness = clamp(surface.roughness, 0.04, 1.0);
|
|
981
|
+
let n = normalize(surface.normalWS);
|
|
982
|
+
|
|
983
|
+
var out : GBufferOutput;
|
|
984
|
+
out.normal_roughness = vec4<f32>(n * 0.5 + 0.5, roughness);
|
|
985
|
+
out.albedo_metallic = vec4<f32>(albedo, metallic);
|
|
986
|
+
out.emissive_ao = vec4<f32>(surface.emissive, surface.occlusion);
|
|
987
|
+
return out;
|
|
988
|
+
}
|
|
989
|
+
|
|
473
990
|
struct TemporalVsOut {
|
|
474
991
|
@builtin(position) clip : vec4<f32>,
|
|
475
992
|
@location(0) uv : vec2<f32>,
|
|
@@ -482,7 +999,6 @@ struct TemporalVsOut {
|
|
|
482
999
|
@location(7) uv7 : vec2<f32>,
|
|
483
1000
|
@location(8) @interpolate(perspective) currentClip : vec4<f32>,
|
|
484
1001
|
@location(9) @interpolate(perspective) previousClip : vec4<f32>,
|
|
485
|
-
@location(10) @interpolate(flat) reactive : f32,
|
|
486
1002
|
#ifdef VERTEX_COLOR_AVAILABLE
|
|
487
1003
|
@location(14) color : vec4<f32>,
|
|
488
1004
|
#endif
|
|
@@ -490,25 +1006,20 @@ struct TemporalVsOut {
|
|
|
490
1006
|
|
|
491
1007
|
@vertex
|
|
492
1008
|
fn vs_temporal(in : VsIn, @builtin(instance_index) idx : u32) -> TemporalVsOut {
|
|
493
|
-
let currentSkin =
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
let previousSkin =
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
1009
|
+
let currentSkin = palette[in.skinIndex.x] * in.skinWeight.x +
|
|
1010
|
+
palette[in.skinIndex.y] * in.skinWeight.y +
|
|
1011
|
+
palette[in.skinIndex.z] * in.skinWeight.z +
|
|
1012
|
+
palette[in.skinIndex.w] * in.skinWeight.w;
|
|
1013
|
+
let previousSkin = previousPalette[in.skinIndex.x] * in.skinWeight.x +
|
|
1014
|
+
previousPalette[in.skinIndex.y] * in.skinWeight.y +
|
|
1015
|
+
previousPalette[in.skinIndex.z] * in.skinWeight.z +
|
|
1016
|
+
previousPalette[in.skinIndex.w] * in.skinWeight.w;
|
|
501
1017
|
let currentWorld = currentSkin * vec4<f32>(in.pos, 1.0);
|
|
502
1018
|
let previousWorld = previousSkin * vec4<f32>(in.pos, 1.0);
|
|
503
1019
|
var out : TemporalVsOut;
|
|
504
1020
|
out.currentClip = view.temporalCurrentViewProj * currentWorld;
|
|
505
1021
|
out.clip = out.currentClip;
|
|
506
1022
|
out.previousClip = view.temporalPreviousViewProj * previousWorld;
|
|
507
|
-
#if STORAGE_BUFFER_AVAILABLE == true
|
|
508
|
-
out.reactive = meshes[0].temporal.x;
|
|
509
|
-
#else
|
|
510
|
-
out.reactive = 1.0;
|
|
511
|
-
#endif
|
|
512
1023
|
out.uv = in.uv;
|
|
513
1024
|
out.uv1 = in.uv1;
|
|
514
1025
|
out.uv2 = in.uv2;
|
|
@@ -534,9 +1045,10 @@ fn temporalVertexAlpha(in : TemporalVsOut) -> f32 {
|
|
|
534
1045
|
|
|
535
1046
|
@fragment
|
|
536
1047
|
fn fs_temporal(in : TemporalVsOut) -> @location(0) vec4<f32> {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
1048
|
+
#if STORAGE_BUFFER_AVAILABLE == true
|
|
1049
|
+
let reactive = meshes[0].temporal.x;
|
|
1050
|
+
#else
|
|
1051
|
+
let reactive = 1.0;
|
|
540
1052
|
#endif
|
|
541
1053
|
return projectPbrSceneTemporal(
|
|
542
1054
|
material.baseColor.a * temporalVertexAlpha(in),
|
|
@@ -548,7 +1060,7 @@ fn fs_temporal(in : TemporalVsOut) -> @location(0) vec4<f32> {
|
|
|
548
1060
|
in.currentClip,
|
|
549
1061
|
in.previousClip,
|
|
550
1062
|
view.temporalProjection,
|
|
551
|
-
|
|
1063
|
+
reactive,
|
|
552
1064
|
in.uv, in.uv1, in.uv2, in.uv3,
|
|
553
1065
|
in.uv4, in.uv5, in.uv6, in.uv7,
|
|
554
1066
|
);
|