@aura3d/rendering 1.5.2 → 2.0.0
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 +8 -2
- package/dist/ArchitecturalLighting.d.ts +35 -0
- package/dist/ArchitecturalLighting.d.ts.map +1 -0
- package/dist/ArchitecturalLighting.js +162 -0
- package/dist/ArchitecturalLighting.js.map +1 -0
- package/dist/ArchitecturalMaterialCatalog.d.ts +1 -1
- package/dist/ArchitecturalMaterialCatalog.d.ts.map +1 -1
- package/dist/ArchitecturalMaterialCatalog.js +1 -1
- package/dist/ArchitecturalMaterialCatalog.js.map +1 -1
- package/dist/ArchitecturalMeasurement.d.ts +27 -0
- package/dist/ArchitecturalMeasurement.d.ts.map +1 -0
- package/dist/ArchitecturalMeasurement.js +112 -0
- package/dist/ArchitecturalMeasurement.js.map +1 -0
- package/dist/CanonicalProductScene.d.ts +13 -0
- package/dist/CanonicalProductScene.d.ts.map +1 -0
- package/dist/CanonicalProductScene.js +78 -0
- package/dist/CanonicalProductScene.js.map +1 -0
- package/dist/CascadedShadowMaps.d.ts +1 -1
- package/dist/CascadedShadowMaps.d.ts.map +1 -1
- package/dist/CascadedShadowMaps.js +1 -1
- package/dist/CascadedShadowMaps.js.map +1 -1
- package/dist/DepthPass.d.ts +1 -1
- package/dist/DepthPass.d.ts.map +1 -1
- package/dist/DepthPass.js +2 -2
- package/dist/DepthPass.js.map +1 -1
- package/dist/EnvironmentBackgroundPass.d.ts +1 -1
- package/dist/EnvironmentBackgroundPass.d.ts.map +1 -1
- package/dist/EnvironmentBackgroundPass.js +2 -2
- package/dist/EnvironmentBackgroundPass.js.map +1 -1
- package/dist/EnvironmentPlatform.js +2 -2
- package/dist/EnvironmentPlatform.js.map +1 -1
- package/dist/ForwardPass.d.ts +1 -1
- package/dist/ForwardPass.d.ts.map +1 -1
- package/dist/ForwardPass.js +24 -10
- package/dist/ForwardPass.js.map +1 -1
- package/dist/Geometry.d.ts +2 -0
- package/dist/Geometry.d.ts.map +1 -1
- package/dist/Geometry.js +15 -0
- package/dist/Geometry.js.map +1 -1
- package/dist/InstancedPBRMaterial.js +1 -1
- package/dist/InstancedPBRMaterial.js.map +1 -1
- package/dist/InstancedUnlitMaterial.js +1 -1
- package/dist/InstancedUnlitMaterial.js.map +1 -1
- package/dist/Material.js +2 -2
- package/dist/Material.js.map +1 -1
- package/dist/MaterialBinding.js +4 -4
- package/dist/MaterialBinding.js.map +1 -1
- package/dist/MaterialInstance.js +2 -2
- package/dist/MaterialInstance.js.map +1 -1
- package/dist/MorphUnlitMaterial.js +1 -1
- package/dist/MorphUnlitMaterial.js.map +1 -1
- package/dist/NormalMappedPBRMaterial.js +1 -1
- package/dist/NormalMappedPBRMaterial.js.map +1 -1
- package/dist/OceanSurface.d.ts +62 -0
- package/dist/OceanSurface.d.ts.map +1 -0
- package/dist/OceanSurface.js +240 -0
- package/dist/OceanSurface.js.map +1 -0
- package/dist/PBRMaterial.d.ts.map +1 -1
- package/dist/PBRMaterial.js +3 -3
- package/dist/PBRMaterial.js.map +1 -1
- package/dist/PortableShaderMaterial.d.ts +60 -0
- package/dist/PortableShaderMaterial.d.ts.map +1 -0
- package/dist/PortableShaderMaterial.js +223 -0
- package/dist/PortableShaderMaterial.js.map +1 -0
- package/dist/PostProcessPass.d.ts.map +1 -1
- package/dist/PostProcessPass.js +30 -6
- package/dist/PostProcessPass.js.map +1 -1
- package/dist/ProceduralTexture.d.ts +27 -0
- package/dist/ProceduralTexture.d.ts.map +1 -0
- package/dist/ProceduralTexture.js +336 -0
- package/dist/ProceduralTexture.js.map +1 -0
- package/dist/ProductTurntable.d.ts +96 -0
- package/dist/ProductTurntable.d.ts.map +1 -0
- package/dist/ProductTurntable.js +639 -0
- package/dist/ProductTurntable.js.map +1 -0
- package/dist/RenderDevice.d.ts +30 -0
- package/dist/RenderDevice.d.ts.map +1 -1
- package/dist/RenderDevice.js.map +1 -1
- package/dist/Renderer.d.ts +3 -2
- package/dist/Renderer.d.ts.map +1 -1
- package/dist/Renderer.js +23 -9
- package/dist/Renderer.js.map +1 -1
- package/dist/RendererPostprocessPlan.js +4 -4
- package/dist/RendererPostprocessPlan.js.map +1 -1
- package/dist/ScreenSpaceLineMaterial.js +1 -1
- package/dist/ScreenSpaceLineMaterial.js.map +1 -1
- package/dist/ShaderChunks.d.ts.map +1 -1
- package/dist/ShaderChunks.js +81 -19
- package/dist/ShaderChunks.js.map +1 -1
- package/dist/ShaderLibrary.d.ts +2 -78
- package/dist/ShaderLibrary.d.ts.map +1 -1
- package/dist/ShaderLibrary.js +127 -793
- package/dist/ShaderLibrary.js.map +1 -1
- package/dist/ShaderLibraryCore.d.ts +100 -0
- package/dist/ShaderLibraryCore.d.ts.map +1 -0
- package/dist/ShaderLibraryCore.js +800 -0
- package/dist/ShaderLibraryCore.js.map +1 -0
- package/dist/ShaderModule.d.ts +1 -1
- package/dist/ShaderModule.d.ts.map +1 -1
- package/dist/ShaderModule.js +4 -2
- package/dist/ShaderModule.js.map +1 -1
- package/dist/ShadowPass.d.ts +1 -1
- package/dist/ShadowPass.d.ts.map +1 -1
- package/dist/ShadowPass.js +6 -4
- package/dist/ShadowPass.js.map +1 -1
- package/dist/SkinnedLitMaterial.js +1 -1
- package/dist/SkinnedLitMaterial.js.map +1 -1
- package/dist/SkinnedUnlitMaterial.js +1 -1
- package/dist/SkinnedUnlitMaterial.js.map +1 -1
- package/dist/SpaceEnvironment.d.ts +54 -0
- package/dist/SpaceEnvironment.d.ts.map +1 -0
- package/dist/SpaceEnvironment.js +116 -0
- package/dist/SpaceEnvironment.js.map +1 -0
- package/dist/TerrainHeightfield.d.ts +60 -0
- package/dist/TerrainHeightfield.d.ts.map +1 -0
- package/dist/TerrainHeightfield.js +239 -0
- package/dist/TerrainHeightfield.js.map +1 -0
- package/dist/TextureBinding.d.ts +14 -0
- package/dist/TextureBinding.d.ts.map +1 -1
- package/dist/TextureBinding.js +17 -0
- package/dist/TextureBinding.js.map +1 -1
- package/dist/TexturedPBRMaterial.js +1 -1
- package/dist/TexturedPBRMaterial.js.map +1 -1
- package/dist/TexturedUnlitMaterial.js +1 -1
- package/dist/TexturedUnlitMaterial.js.map +1 -1
- package/dist/UnlitMaterial.js +1 -1
- package/dist/UnlitMaterial.js.map +1 -1
- package/dist/VegetationFixtures.d.ts +1 -1
- package/dist/VegetationFixtures.d.ts.map +1 -1
- package/dist/VegetationFixtures.js +1 -1
- package/dist/VegetationFixtures.js.map +1 -1
- package/dist/VegetationScatter.d.ts +68 -0
- package/dist/VegetationScatter.d.ts.map +1 -0
- package/dist/VegetationScatter.js +241 -0
- package/dist/VegetationScatter.js.map +1 -0
- package/dist/VoxelWorld.d.ts +51 -0
- package/dist/VoxelWorld.d.ts.map +1 -0
- package/dist/VoxelWorld.js +183 -0
- package/dist/VoxelWorld.js.map +1 -0
- package/dist/Weather.d.ts +44 -0
- package/dist/Weather.d.ts.map +1 -0
- package/dist/Weather.js +140 -0
- package/dist/Weather.js.map +1 -0
- package/dist/WebGL2Device.d.ts +22 -0
- package/dist/WebGL2Device.d.ts.map +1 -1
- package/dist/WebGL2Device.js +134 -23
- package/dist/WebGL2Device.js.map +1 -1
- package/dist/WebGPUDevice.d.ts +19 -2
- package/dist/WebGPUDevice.d.ts.map +1 -1
- package/dist/WebGPUDevice.js +188 -9
- package/dist/WebGPUDevice.js.map +1 -1
- package/dist/index.d.ts +25 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -19
- package/dist/index.js.map +1 -1
- package/dist/lean/LeanProductRenderer.d.ts +29 -0
- package/dist/lean/LeanProductRenderer.d.ts.map +1 -0
- package/dist/lean/LeanProductRenderer.js +38 -0
- package/dist/lean/LeanProductRenderer.js.map +1 -0
- package/dist/lean/LeanProductionRenderer.d.ts +38 -0
- package/dist/lean/LeanProductionRenderer.d.ts.map +1 -0
- package/dist/lean/LeanProductionRenderer.js +88 -0
- package/dist/lean/LeanProductionRenderer.js.map +1 -0
- package/dist/lean-runtime.d.ts +18 -0
- package/dist/lean-runtime.d.ts.map +1 -0
- package/dist/lean-runtime.js +13 -0
- package/dist/lean-runtime.js.map +1 -0
- package/dist/postprocess/EffectComposer.d.ts.map +1 -1
- package/dist/postprocess/EffectComposer.js +1 -3
- package/dist/postprocess/EffectComposer.js.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
- package/dist/production-runtime/PBRHDRPipeline.js +5 -1
- package/dist/production-runtime/PBRHDRPipeline.js.map +1 -1
- package/dist/production-runtime/ProductionRendererTypes.d.ts +9 -0
- package/dist/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
- package/dist/production-runtime/ProductionRendererTypes.js.map +1 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.d.ts +5 -0
- package/dist/production-runtime/ProductionRuntimeRenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionRuntimeRenderer.js +53 -5
- package/dist/production-runtime/ProductionRuntimeRenderer.js.map +1 -1
- package/dist/production-runtime/ProductionWebGL2Renderer.d.ts +10 -0
- package/dist/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGL2Renderer.js +21 -2
- package/dist/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
- package/dist/production-runtime/ProductionWebGPURenderer.js +4 -1
- package/dist/production-runtime/ProductionWebGPURenderer.js.map +1 -1
- package/dist/webgpu-device-entry.d.ts +25 -0
- package/dist/webgpu-device-entry.d.ts.map +1 -0
- package/dist/webgpu-device-entry.js +24 -0
- package/dist/webgpu-device-entry.js.map +1 -0
- package/dist/webgpu.d.ts +25 -0
- package/dist/webgpu.d.ts.map +1 -0
- package/dist/webgpu.js +24 -0
- package/dist/webgpu.js.map +1 -0
- package/package.json +11 -3
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
import { ShaderPreprocessor } from "./ShaderPreprocessor.js";
|
|
2
|
+
export { DEFAULT_PBR_SHADER_MARKER, DEFAULT_PBR_SHADER_NAME } from "./PBRMaterial.js";
|
|
3
|
+
import { DEFAULT_PBR_SHADER_MARKER, DEFAULT_PBR_SHADER_NAME } from "./PBRMaterial.js";
|
|
4
|
+
import { SHADER_CHUNKS, validateShaderChunks } from "./ShaderChunks.js";
|
|
5
|
+
export class ShaderLibrary {
|
|
6
|
+
shaders = new Map();
|
|
7
|
+
chunks = new Map();
|
|
8
|
+
preprocessor = new ShaderPreprocessor();
|
|
9
|
+
variantCache = new Map();
|
|
10
|
+
revision = 0;
|
|
11
|
+
register(shader) {
|
|
12
|
+
if (this.shaders.has(shader.name)) {
|
|
13
|
+
throw new Error(`Shader is already registered: ${shader.name}`);
|
|
14
|
+
}
|
|
15
|
+
this.assertMarker(shader);
|
|
16
|
+
this.assertVariants(shader);
|
|
17
|
+
this.shaders.set(shader.name, shader);
|
|
18
|
+
this.variantCache.clear();
|
|
19
|
+
this.revision += 1;
|
|
20
|
+
}
|
|
21
|
+
replace(shader) {
|
|
22
|
+
if (!this.shaders.has(shader.name)) {
|
|
23
|
+
throw new Error(`Shader is not registered: ${shader.name}`);
|
|
24
|
+
}
|
|
25
|
+
this.assertMarker(shader);
|
|
26
|
+
this.assertVariants(shader);
|
|
27
|
+
this.shaders.set(shader.name, shader);
|
|
28
|
+
this.variantCache.clear();
|
|
29
|
+
this.revision += 1;
|
|
30
|
+
}
|
|
31
|
+
unregister(name) {
|
|
32
|
+
const removed = this.shaders.delete(name);
|
|
33
|
+
if (removed) {
|
|
34
|
+
this.variantCache.clear();
|
|
35
|
+
this.revision += 1;
|
|
36
|
+
}
|
|
37
|
+
return removed;
|
|
38
|
+
}
|
|
39
|
+
getRevision() {
|
|
40
|
+
return this.revision;
|
|
41
|
+
}
|
|
42
|
+
registerChunk(name, source) {
|
|
43
|
+
if (this.chunks.has(name)) {
|
|
44
|
+
throw new Error(`Shader chunk is already registered: ${name}`);
|
|
45
|
+
}
|
|
46
|
+
this.chunks.set(name, source);
|
|
47
|
+
this.variantCache.clear();
|
|
48
|
+
this.revision += 1;
|
|
49
|
+
}
|
|
50
|
+
get(name) {
|
|
51
|
+
const shader = this.shaders.get(name);
|
|
52
|
+
if (!shader) {
|
|
53
|
+
throw new Error(`Shader is not registered: ${name}`);
|
|
54
|
+
}
|
|
55
|
+
return shader;
|
|
56
|
+
}
|
|
57
|
+
compileSource(name, options = {}) {
|
|
58
|
+
const shader = this.get(name);
|
|
59
|
+
const includes = new Map([...this.chunks, ...(options.includes ?? new Map())]);
|
|
60
|
+
const preprocessOptions = { ...options, includes };
|
|
61
|
+
const vertex = this.preprocessor.preprocess(shader.vertex, preprocessOptions).source;
|
|
62
|
+
const fragment = this.preprocessor.preprocess(shader.fragment, preprocessOptions).source;
|
|
63
|
+
if (!vertex.includes(shader.marker) || !fragment.includes(shader.marker)) {
|
|
64
|
+
throw new Error(`Shader marker ${shader.marker} was not preserved for ${name}`);
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
label: name,
|
|
68
|
+
marker: shader.marker,
|
|
69
|
+
vertex,
|
|
70
|
+
fragment,
|
|
71
|
+
...(shader.webgpu ? { webgpu: shader.webgpu } : {}),
|
|
72
|
+
...(shader.portableBindings ? { portableBindings: shader.portableBindings } : {})
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
compileVariant(name, variantName, options = {}) {
|
|
76
|
+
const shader = this.get(name);
|
|
77
|
+
const variant = shader.variants?.find((candidate) => candidate.name === variantName);
|
|
78
|
+
if (!variant) {
|
|
79
|
+
throw new Error(`Shader variant is not registered: ${name}:${variantName}`);
|
|
80
|
+
}
|
|
81
|
+
const compileOptions = {
|
|
82
|
+
...options,
|
|
83
|
+
defines: {
|
|
84
|
+
...(variant.defines ?? {}),
|
|
85
|
+
...(options.defines ?? {})
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const cacheKey = variantCacheKey(name, variantName, compileOptions);
|
|
89
|
+
const cached = this.variantCache.get(cacheKey);
|
|
90
|
+
if (cached) {
|
|
91
|
+
return cached;
|
|
92
|
+
}
|
|
93
|
+
const compiled = this.compileSource(name, compileOptions);
|
|
94
|
+
const labeled = { ...compiled, label: `${name}:${variantName}` };
|
|
95
|
+
this.variantCache.set(cacheKey, labeled);
|
|
96
|
+
return labeled;
|
|
97
|
+
}
|
|
98
|
+
names() {
|
|
99
|
+
return [...this.shaders.keys()];
|
|
100
|
+
}
|
|
101
|
+
assertMarker(shader) {
|
|
102
|
+
if (!shader.marker.trim()) {
|
|
103
|
+
throw new Error(`Shader ${shader.name} must declare a non-empty source marker`);
|
|
104
|
+
}
|
|
105
|
+
if (!shader.vertex.includes(shader.marker) || !shader.fragment.includes(shader.marker)) {
|
|
106
|
+
throw new Error(`Shader ${shader.name} must include marker ${shader.marker} in both stages`);
|
|
107
|
+
}
|
|
108
|
+
if (shader.webgpu && (!shader.webgpu.vertex.includes(shader.marker) || !shader.webgpu.fragment.includes(shader.marker))) {
|
|
109
|
+
throw new Error(`Shader ${shader.name} must include marker ${shader.marker} in both WebGPU stages`);
|
|
110
|
+
}
|
|
111
|
+
if ((shader.webgpu === undefined) !== (shader.portableBindings === undefined)) {
|
|
112
|
+
throw new Error(`Portable shader ${shader.name} must provide both webgpu sources and portableBindings`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
assertVariants(shader) {
|
|
116
|
+
const seen = new Set();
|
|
117
|
+
for (const variant of shader.variants ?? []) {
|
|
118
|
+
if (!variant.name.trim()) {
|
|
119
|
+
throw new Error(`Shader ${shader.name} has a variant with an empty name`);
|
|
120
|
+
}
|
|
121
|
+
if (seen.has(variant.name)) {
|
|
122
|
+
throw new Error(`Shader variant is already registered: ${shader.name}:${variant.name}`);
|
|
123
|
+
}
|
|
124
|
+
seen.add(variant.name);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function variantCacheKey(name, variantName, options) {
|
|
129
|
+
return JSON.stringify({
|
|
130
|
+
name,
|
|
131
|
+
variantName,
|
|
132
|
+
defines: Object.entries(options.defines ?? {}).sort(([left], [right]) => left.localeCompare(right)),
|
|
133
|
+
includes: [...(options.includes ?? new Map()).entries()].sort(([left], [right]) => left.localeCompare(right))
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
export const DEFAULT_UNLIT_SHADER_NAME = "aura3d/unlit";
|
|
137
|
+
export const DEFAULT_UNLIT_SHADER_MARKER = "@aura3d-shader:unlit";
|
|
138
|
+
export const DEFAULT_INSTANCED_UNLIT_SHADER_NAME = "aura3d/instanced-unlit";
|
|
139
|
+
export const DEFAULT_INSTANCED_UNLIT_SHADER_MARKER = "@aura3d-shader:instanced-unlit";
|
|
140
|
+
export const DEFAULT_INSTANCED_PBR_SHADER_NAME = "aura3d/instanced-pbr";
|
|
141
|
+
export const DEFAULT_INSTANCED_PBR_SHADER_MARKER = "@aura3d-shader:instanced-pbr";
|
|
142
|
+
export const DEFAULT_TEXTURED_UNLIT_SHADER_NAME = "aura3d/textured-unlit";
|
|
143
|
+
export const DEFAULT_TEXTURED_UNLIT_SHADER_MARKER = "@aura3d-shader:textured-unlit";
|
|
144
|
+
export const DEFAULT_SKINNED_UNLIT_SHADER_NAME = "aura3d/skinned-unlit";
|
|
145
|
+
export const DEFAULT_SKINNED_UNLIT_SHADER_MARKER = "@aura3d-shader:skinned-unlit";
|
|
146
|
+
export const DEFAULT_SKINNED_LIT_SHADER_NAME = "aura3d/skinned-lit";
|
|
147
|
+
export const DEFAULT_SKINNED_LIT_SHADER_MARKER = "@aura3d-shader:skinned-lit";
|
|
148
|
+
/**
|
|
149
|
+
* Eight-influence skinned shaders. These read a second `JOINTS_1`/`WEIGHTS_1`
|
|
150
|
+
* attribute set and select between uniform-array and data-texture joint palettes at
|
|
151
|
+
* runtime through `u_jointPaletteMode`, so a single program serves both small rigs
|
|
152
|
+
* and rigs above the uniform-array joint limit.
|
|
153
|
+
*/
|
|
154
|
+
export const DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_NAME = "aura3d/skinned-unlit-8";
|
|
155
|
+
export const DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_MARKER = "@aura3d-shader:skinned-unlit-8";
|
|
156
|
+
export const DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_NAME = "aura3d/skinned-lit-8";
|
|
157
|
+
export const DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_MARKER = "@aura3d-shader:skinned-lit-8";
|
|
158
|
+
export const DEFAULT_MORPH_UNLIT_SHADER_NAME = "aura3d/morph-unlit";
|
|
159
|
+
export const DEFAULT_MORPH_UNLIT_SHADER_MARKER = "@aura3d-shader:morph-unlit";
|
|
160
|
+
export const DEFAULT_NORMAL_MAPPED_PBR_SHADER_NAME = "aura3d/pbr-normal-map";
|
|
161
|
+
export const DEFAULT_NORMAL_MAPPED_PBR_SHADER_MARKER = "@aura3d-shader:pbr-normal-map";
|
|
162
|
+
export const DEFAULT_TEXTURED_PBR_SHADER_NAME = "aura3d/pbr-textured";
|
|
163
|
+
export const DEFAULT_TEXTURED_PBR_SHADER_MARKER = "@aura3d-shader:pbr-textured";
|
|
164
|
+
export const DEFAULT_TEXTURED_PBR_CLEARCOAT_TEXTURES_VARIANT = "clearcoat-textures";
|
|
165
|
+
export const DEFAULT_TEXTURED_PBR_TRANSMISSION_VOLUME_TEXTURES_VARIANT = "transmission-volume-textures";
|
|
166
|
+
export const DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES_VARIANT = "specular-sheen-anisotropy-textures";
|
|
167
|
+
export const DEFAULT_TEXTURED_PBR_IRIDESCENCE_TEXTURES_VARIANT = "iridescence-textures";
|
|
168
|
+
export const DEFAULT_TEXTURED_PBR_CLEARCOAT_TRANSMISSION_VOLUME_TEXTURES_VARIANT = "clearcoat-transmission-volume-textures";
|
|
169
|
+
export const DEFAULT_TEXTURED_PBR_CLEARCOAT_SPECULAR_TEXTURES_VARIANT = "clearcoat-specular-textures";
|
|
170
|
+
export const DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_IRIDESCENCE_TEXTURES_VARIANT = "specular-sheen-anisotropy-iridescence-textures";
|
|
171
|
+
/**
|
|
172
|
+
* True screen-space fat lines, equivalent in intent to Three.js `Line2`/`LineMaterial`.
|
|
173
|
+
* Width is specified in pixels and stays constant across distance, FOV, viewport size,
|
|
174
|
+
* and device pixel ratio.
|
|
175
|
+
*/
|
|
176
|
+
export const DEFAULT_SCREEN_SPACE_LINE_SHADER_NAME = "aura3d/screen-space-line";
|
|
177
|
+
export const DEFAULT_SCREEN_SPACE_LINE_SHADER_MARKER = "@aura3d-shader:screen-space-line";
|
|
178
|
+
export const DEFAULT_DEPTH_SHADER_NAME = "aura3d/depth";
|
|
179
|
+
export const DEFAULT_DEPTH_SHADER_MARKER = "@aura3d-shader:depth";
|
|
180
|
+
export const DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_NAME = "aura3d/environment-background";
|
|
181
|
+
export const DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_MARKER = "@aura3d-shader:environment-background";
|
|
182
|
+
export function registerLeanUnlitShader(library) {
|
|
183
|
+
library.register({
|
|
184
|
+
name: DEFAULT_UNLIT_SHADER_NAME,
|
|
185
|
+
marker: DEFAULT_UNLIT_SHADER_MARKER,
|
|
186
|
+
vertex: `#version 300 es
|
|
187
|
+
// ${DEFAULT_UNLIT_SHADER_MARKER}
|
|
188
|
+
precision highp float;
|
|
189
|
+
layout(location = 0) in vec3 a_position;
|
|
190
|
+
layout(location = 4) in vec4 a_color;
|
|
191
|
+
uniform mat4 u_modelViewProjection;
|
|
192
|
+
uniform float u_pointSize;
|
|
193
|
+
out vec4 v_vertexColor;
|
|
194
|
+
void main() {
|
|
195
|
+
v_vertexColor = a_color;
|
|
196
|
+
gl_PointSize = max(u_pointSize, 1.0);
|
|
197
|
+
gl_Position = u_modelViewProjection * vec4(a_position, 1.0);
|
|
198
|
+
}
|
|
199
|
+
`,
|
|
200
|
+
fragment: `#version 300 es
|
|
201
|
+
// ${DEFAULT_UNLIT_SHADER_MARKER}
|
|
202
|
+
precision highp float;
|
|
203
|
+
uniform vec4 u_baseColor;
|
|
204
|
+
uniform float u_alphaCutoff;
|
|
205
|
+
uniform float u_roundPoints;
|
|
206
|
+
in vec4 v_vertexColor;
|
|
207
|
+
out vec4 outColor;
|
|
208
|
+
void main() {
|
|
209
|
+
if (u_roundPoints > 0.5) {
|
|
210
|
+
vec2 pointUv = gl_PointCoord * 2.0 - 1.0;
|
|
211
|
+
float radius = dot(pointUv, pointUv);
|
|
212
|
+
if (radius > 1.0) discard;
|
|
213
|
+
}
|
|
214
|
+
vec4 base = u_baseColor * v_vertexColor;
|
|
215
|
+
if (base.a < u_alphaCutoff) discard;
|
|
216
|
+
outColor = base;
|
|
217
|
+
}
|
|
218
|
+
`
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
export function registerLeanPbrShader(library) {
|
|
222
|
+
library.register({
|
|
223
|
+
name: DEFAULT_PBR_SHADER_NAME,
|
|
224
|
+
marker: DEFAULT_PBR_SHADER_MARKER,
|
|
225
|
+
vertex: `#version 300 es
|
|
226
|
+
// ${DEFAULT_PBR_SHADER_MARKER}
|
|
227
|
+
precision highp float;
|
|
228
|
+
layout(location = 0) in vec3 a_position;
|
|
229
|
+
layout(location = 1) in vec3 a_normal;
|
|
230
|
+
layout(location = 4) in vec4 a_color;
|
|
231
|
+
uniform mat4 u_modelViewProjection;
|
|
232
|
+
uniform mat4 u_modelMatrix;
|
|
233
|
+
uniform mat4 u_normalMatrix;
|
|
234
|
+
out vec3 v_normal;
|
|
235
|
+
out vec3 v_worldPosition;
|
|
236
|
+
out vec4 v_vertexColor;
|
|
237
|
+
void main() {
|
|
238
|
+
v_normal = mat3(u_normalMatrix) * a_normal;
|
|
239
|
+
v_worldPosition = (u_modelMatrix * vec4(a_position, 1.0)).xyz;
|
|
240
|
+
v_vertexColor = a_color;
|
|
241
|
+
gl_Position = u_modelViewProjection * vec4(a_position, 1.0);
|
|
242
|
+
}
|
|
243
|
+
`,
|
|
244
|
+
fragment: `#version 300 es
|
|
245
|
+
// ${DEFAULT_PBR_SHADER_MARKER}
|
|
246
|
+
precision highp float;
|
|
247
|
+
#include <lighting_common>
|
|
248
|
+
#include <pbr_common>
|
|
249
|
+
uniform vec4 u_baseColor;
|
|
250
|
+
uniform float u_alphaCutoff;
|
|
251
|
+
uniform float u_metallic;
|
|
252
|
+
uniform float u_roughness;
|
|
253
|
+
uniform vec3 u_environmentColor;
|
|
254
|
+
uniform float u_environmentIntensity;
|
|
255
|
+
uniform vec3 u_environmentSkyColor;
|
|
256
|
+
uniform vec3 u_environmentHorizonColor;
|
|
257
|
+
uniform vec3 u_environmentGroundColor;
|
|
258
|
+
uniform vec3 u_environmentSpecularColor;
|
|
259
|
+
uniform float u_environmentMapIntensity;
|
|
260
|
+
uniform float u_environmentSpecularIntensity;
|
|
261
|
+
uniform sampler2D u_environmentMapTexture;
|
|
262
|
+
uniform samplerCube u_environmentCubeMapTexture;
|
|
263
|
+
uniform float u_environmentCubeMapTextureEnabled;
|
|
264
|
+
uniform float u_environmentMapTextureEnabled;
|
|
265
|
+
uniform float u_environmentMapTextureIntensity;
|
|
266
|
+
uniform float u_environmentMapTextureSpecularIntensity;
|
|
267
|
+
uniform float u_environmentMapTextureRotation;
|
|
268
|
+
uniform float u_environmentMapTextureMipCount;
|
|
269
|
+
uniform float u_environmentMapTextureEncoding;
|
|
270
|
+
uniform sampler2D u_environmentBrdfLutTexture;
|
|
271
|
+
uniform float u_environmentBrdfLutEnabled;
|
|
272
|
+
uniform vec3 u_emissiveColor;
|
|
273
|
+
uniform float u_emissiveStrength;
|
|
274
|
+
uniform float u_clearcoatFactor;
|
|
275
|
+
uniform float u_clearcoatRoughnessFactor;
|
|
276
|
+
uniform float u_transmissionFactor;
|
|
277
|
+
uniform float u_diffuseTransmissionFactor;
|
|
278
|
+
uniform vec3 u_diffuseTransmissionColorFactor;
|
|
279
|
+
uniform float u_transmissionFallbackEnergy;
|
|
280
|
+
uniform float u_volumeThicknessFactor;
|
|
281
|
+
uniform float u_volumeAttenuationDistance;
|
|
282
|
+
uniform vec3 u_volumeAttenuationColor;
|
|
283
|
+
uniform float u_transmissionParallaxStrength;
|
|
284
|
+
uniform vec3 u_transmissionParallaxBoxMin;
|
|
285
|
+
uniform vec3 u_transmissionParallaxBoxMax;
|
|
286
|
+
uniform float u_transmissionBounceCount;
|
|
287
|
+
uniform float u_transmissionCausticStrength;
|
|
288
|
+
uniform float u_ior;
|
|
289
|
+
uniform float u_specularFactor;
|
|
290
|
+
uniform vec3 u_specularColorFactor;
|
|
291
|
+
uniform vec3 u_sheenColorFactor;
|
|
292
|
+
uniform float u_sheenRoughnessFactor;
|
|
293
|
+
uniform float u_anisotropyStrength;
|
|
294
|
+
uniform float u_anisotropyRotation;
|
|
295
|
+
uniform float u_iridescenceFactor;
|
|
296
|
+
uniform float u_iridescenceIor;
|
|
297
|
+
uniform float u_iridescenceThicknessMinimum;
|
|
298
|
+
uniform float u_iridescenceThicknessMaximum;
|
|
299
|
+
uniform float u_dispersion;
|
|
300
|
+
uniform float u_lightCount;
|
|
301
|
+
uniform vec4 u_lightData[96];
|
|
302
|
+
uniform float u_clusteredLightEnabled;
|
|
303
|
+
uniform vec2 u_clusterGridSize;
|
|
304
|
+
uniform vec2 u_clusterViewportSize;
|
|
305
|
+
uniform sampler2D u_clusterLightData;
|
|
306
|
+
uniform sampler2D u_clusterLightIndices;
|
|
307
|
+
uniform sampler2D u_shadowMapTexture;
|
|
308
|
+
uniform float u_shadowMapEnabled;
|
|
309
|
+
uniform mat4 u_shadowMapMatrix;
|
|
310
|
+
uniform float u_shadowMapStrength;
|
|
311
|
+
uniform float u_shadowMapBias;
|
|
312
|
+
uniform float u_shadowMapSlopeBias;
|
|
313
|
+
uniform vec2 u_shadowMapTexelSize;
|
|
314
|
+
uniform float u_shadowPcfSampleCount;
|
|
315
|
+
uniform vec4 u_shadowPcfSamples[32];
|
|
316
|
+
uniform sampler2D u_pointShadowMapTexture;
|
|
317
|
+
uniform float u_pointShadowMapEnabled;
|
|
318
|
+
uniform vec3 u_pointShadowLightPosition;
|
|
319
|
+
uniform float u_pointShadowRange;
|
|
320
|
+
uniform mat4 u_pointShadowFaceMatrices[6];
|
|
321
|
+
uniform vec4 u_pointShadowFaceRects[6];
|
|
322
|
+
uniform float u_pointShadowStrength;
|
|
323
|
+
uniform float u_pointShadowBias;
|
|
324
|
+
uniform float u_pointShadowSlopeBias;
|
|
325
|
+
uniform vec2 u_pointShadowTexelSize;
|
|
326
|
+
uniform float u_pointShadowPcfSampleCount;
|
|
327
|
+
uniform vec4 u_pointShadowPcfSamples[32];
|
|
328
|
+
uniform float u_outputColorSpace;
|
|
329
|
+
uniform vec3 u_cameraPosition;
|
|
330
|
+
uniform float u_environmentFogEnabled;
|
|
331
|
+
uniform float u_environmentFogMode;
|
|
332
|
+
uniform vec3 u_environmentFogColor;
|
|
333
|
+
uniform float u_environmentFogNear;
|
|
334
|
+
uniform float u_environmentFogFar;
|
|
335
|
+
uniform float u_environmentFogDensity;
|
|
336
|
+
uniform float u_environmentFogHeightFalloff;
|
|
337
|
+
uniform float u_environmentFogHeightReference;
|
|
338
|
+
uniform float u_environmentFogMaxOpacity;
|
|
339
|
+
in vec3 v_normal;
|
|
340
|
+
in vec3 v_worldPosition;
|
|
341
|
+
in vec4 v_vertexColor;
|
|
342
|
+
out vec4 outColor;
|
|
343
|
+
#include <environment_fog_common>
|
|
344
|
+
vec2 a3dEnvironmentEquirectUv(vec3 direction, float rotation) {
|
|
345
|
+
vec3 d = normalize(direction);
|
|
346
|
+
float u = atan(d.z, d.x) / 6.28318530718 + 0.5 + rotation;
|
|
347
|
+
float v = acos(clamp(d.y, -1.0, 1.0)) / 3.14159265359;
|
|
348
|
+
return vec2(fract(u), clamp(v, 0.0, 1.0));
|
|
349
|
+
}
|
|
350
|
+
vec3 a3dEnvironmentCubeDirection(vec3 direction, float rotation) {
|
|
351
|
+
float angle = rotation * 6.28318530718;
|
|
352
|
+
float c = cos(angle);
|
|
353
|
+
float s = sin(angle);
|
|
354
|
+
vec3 d = normalize(direction);
|
|
355
|
+
return normalize(vec3(c * d.x - s * d.z, d.y, s * d.x + c * d.z));
|
|
356
|
+
}
|
|
357
|
+
vec3 a3dPbrDecodeEnvironmentSrgb(vec3 encodedColor) {
|
|
358
|
+
return max(encodedColor, vec3(0.0));
|
|
359
|
+
}
|
|
360
|
+
vec3 a3dPbrDecodeEnvironmentRgbe(vec4 encodedSample) {
|
|
361
|
+
float exponent = encodedSample.a * 255.0;
|
|
362
|
+
float scale = exponent <= 0.0 ? 0.0 : exp2(exponent - 128.0) * (255.0 / 256.0);
|
|
363
|
+
return max(encodedSample.rgb * scale, vec3(0.0));
|
|
364
|
+
}
|
|
365
|
+
vec3 a3dPbrDecodeEnvironmentSample(vec4 encodedSample) {
|
|
366
|
+
if (u_environmentMapTextureEncoding > 1.5) return max(encodedSample.rgb, vec3(0.0));
|
|
367
|
+
if (u_environmentMapTextureEncoding > 0.5) return a3dPbrDecodeEnvironmentRgbe(encodedSample);
|
|
368
|
+
return a3dPbrDecodeEnvironmentSrgb(encodedSample.rgb);
|
|
369
|
+
}
|
|
370
|
+
vec3 a3dPbrBoundHdrTransmissionRadiance(vec3 radiance) {
|
|
371
|
+
vec3 nonNegative = max(radiance, vec3(0.0));
|
|
372
|
+
return nonNegative / (vec3(1.0) + max(nonNegative - vec3(1.0), vec3(0.0)));
|
|
373
|
+
}
|
|
374
|
+
vec3 a3dPbrBoundHdrSpecularRadiance(vec3 radiance) {
|
|
375
|
+
vec3 nonNegative = max(radiance, vec3(0.0));
|
|
376
|
+
vec3 softKnee = nonNegative / (vec3(1.0) + max(nonNegative - vec3(1.0), vec3(0.0)) * 0.58);
|
|
377
|
+
float maxChannel = max(max(softKnee.r, softKnee.g), softKnee.b);
|
|
378
|
+
return maxChannel > 1.65 ? softKnee * (1.65 / maxChannel) : softKnee;
|
|
379
|
+
}
|
|
380
|
+
vec3 a3dPbrClampSampledSpecularEdgeEnergy(vec3 radiance, float nDotV, float roughness) {
|
|
381
|
+
float faceOn = smoothstep(0.12, 0.55, clamp(nDotV, 0.0, 1.0));
|
|
382
|
+
float roughEnergy = mix(0.6, 1.0, clamp(roughness, 0.0, 1.0));
|
|
383
|
+
float edgeCap = mix(0.12, 1.2, faceOn) * roughEnergy;
|
|
384
|
+
float edgeScale = mix(0.14, 0.92, faceOn);
|
|
385
|
+
vec3 bounded = min(radiance * edgeScale, vec3(edgeCap));
|
|
386
|
+
return max(bounded, vec3(0.0));
|
|
387
|
+
}
|
|
388
|
+
vec4 a3dPbrEnvironmentSampleRaw(vec3 direction, float lod) {
|
|
389
|
+
vec4 equirectSample = textureLod(u_environmentMapTexture, a3dEnvironmentEquirectUv(direction, u_environmentMapTextureRotation), lod);
|
|
390
|
+
vec4 cubeSample = textureLod(u_environmentCubeMapTexture, a3dEnvironmentCubeDirection(direction, u_environmentMapTextureRotation), lod);
|
|
391
|
+
return mix(equirectSample, cubeSample, step(0.5, u_environmentCubeMapTextureEnabled));
|
|
392
|
+
}
|
|
393
|
+
vec3 a3dPbrBoxProjectedDirection(vec3 worldPosition, vec3 direction, vec3 boxMin, vec3 boxMax) {
|
|
394
|
+
vec3 safeDirection = normalize(direction);
|
|
395
|
+
vec3 invDirection = 1.0 / max(abs(safeDirection), vec3(0.0001)) * sign(safeDirection);
|
|
396
|
+
vec3 firstPlane = mix(boxMin, boxMax, step(vec3(0.0), safeDirection));
|
|
397
|
+
vec3 distances = (firstPlane - worldPosition) * invDirection;
|
|
398
|
+
float travel = min(min(
|
|
399
|
+
distances.x > 0.0 ? distances.x : 100000.0,
|
|
400
|
+
distances.y > 0.0 ? distances.y : 100000.0
|
|
401
|
+
), distances.z > 0.0 ? distances.z : 100000.0);
|
|
402
|
+
vec3 hitPosition = worldPosition + safeDirection * travel;
|
|
403
|
+
vec3 boxCenter = (boxMin + boxMax) * 0.5;
|
|
404
|
+
return normalize(hitPosition - boxCenter);
|
|
405
|
+
}
|
|
406
|
+
float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
407
|
+
if (u_shadowMapEnabled < 0.5) return 1.0;
|
|
408
|
+
vec4 lightPosition = u_shadowMapMatrix * vec4(worldPosition, 1.0);
|
|
409
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
410
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
411
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
412
|
+
vec3 receiverNormal = normalize(normal);
|
|
413
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
414
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
415
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
416
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
417
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
418
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
419
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
420
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
421
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
422
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
423
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
424
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
425
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
426
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
427
|
+
float shadowed = 0.0;
|
|
428
|
+
float totalWeight = 0.0;
|
|
429
|
+
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
430
|
+
for (int i = 0; i < 32; ++i) {
|
|
431
|
+
if (i >= sampleCount) break;
|
|
432
|
+
vec4 sampleData = u_shadowPcfSamples[i];
|
|
433
|
+
float weight = max(sampleData.z, 0.0);
|
|
434
|
+
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
435
|
+
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
436
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
437
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
438
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
439
|
+
totalWeight += weight;
|
|
440
|
+
}
|
|
441
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
442
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_shadowMapStrength, 0.0, 1.0));
|
|
443
|
+
}
|
|
444
|
+
float a3dPointShadowFaceIndex(vec3 direction) {
|
|
445
|
+
vec3 absoluteDirection = abs(direction);
|
|
446
|
+
if (absoluteDirection.x >= absoluteDirection.y && absoluteDirection.x >= absoluteDirection.z) return direction.x >= 0.0 ? 0.0 : 1.0;
|
|
447
|
+
if (absoluteDirection.y >= absoluteDirection.x && absoluteDirection.y >= absoluteDirection.z) return direction.y >= 0.0 ? 2.0 : 3.0;
|
|
448
|
+
return direction.z >= 0.0 ? 4.0 : 5.0;
|
|
449
|
+
}
|
|
450
|
+
float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
451
|
+
if (u_pointShadowMapEnabled < 0.5) return 1.0;
|
|
452
|
+
vec3 lightToFragment = worldPosition - u_pointShadowLightPosition;
|
|
453
|
+
float distanceToLight = length(lightToFragment);
|
|
454
|
+
if (distanceToLight > u_pointShadowRange) return 1.0;
|
|
455
|
+
int faceIndex = int(a3dPointShadowFaceIndex(lightToFragment));
|
|
456
|
+
vec4 lightPosition = u_pointShadowFaceMatrices[faceIndex] * vec4(worldPosition, 1.0);
|
|
457
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
458
|
+
vec2 localUv = projected.xy * 0.5 + 0.5;
|
|
459
|
+
if (localUv.x < 0.0 || localUv.x > 1.0 || localUv.y < 0.0 || localUv.y > 1.0) return 1.0;
|
|
460
|
+
vec4 rect = u_pointShadowFaceRects[faceIndex];
|
|
461
|
+
vec2 uv = rect.xy + localUv * rect.zw;
|
|
462
|
+
vec3 receiverNormal = normalize(normal);
|
|
463
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
464
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
465
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
466
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
467
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
468
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
469
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
470
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
471
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
472
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
473
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
474
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
475
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
476
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
477
|
+
float shadowed = 0.0;
|
|
478
|
+
float totalWeight = 0.0;
|
|
479
|
+
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
480
|
+
for (int i = 0; i < 32; ++i) {
|
|
481
|
+
if (i >= sampleCount) break;
|
|
482
|
+
vec4 sampleData = u_pointShadowPcfSamples[i];
|
|
483
|
+
float weight = max(sampleData.z, 0.0);
|
|
484
|
+
vec2 offset = sampleData.xy * u_pointShadowTexelSize;
|
|
485
|
+
float storedDepth = texture(u_pointShadowMapTexture, uv + offset).r;
|
|
486
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
487
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
488
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
489
|
+
totalWeight += weight;
|
|
490
|
+
}
|
|
491
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
492
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
493
|
+
}
|
|
494
|
+
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
495
|
+
vec3 color = max(linearColor, vec3(0.0));
|
|
496
|
+
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
497
|
+
vec3 srgb = pow(filmic, vec3(1.0 / 2.2));
|
|
498
|
+
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
499
|
+
}
|
|
500
|
+
void main() {
|
|
501
|
+
vec3 normal = normalize(v_normal);
|
|
502
|
+
if (!gl_FrontFacing) normal = -normal;
|
|
503
|
+
vec3 viewDirection = normalize(u_cameraPosition - v_worldPosition);
|
|
504
|
+
vec3 materialBase = a3dApplyAdvancedPbrLobes(
|
|
505
|
+
u_baseColor.rgb * v_vertexColor.rgb,
|
|
506
|
+
u_clearcoatFactor,
|
|
507
|
+
u_clearcoatRoughnessFactor,
|
|
508
|
+
u_transmissionFactor,
|
|
509
|
+
u_diffuseTransmissionFactor,
|
|
510
|
+
u_diffuseTransmissionColorFactor,
|
|
511
|
+
u_transmissionFallbackEnergy,
|
|
512
|
+
u_volumeThicknessFactor,
|
|
513
|
+
u_volumeAttenuationDistance,
|
|
514
|
+
u_volumeAttenuationColor,
|
|
515
|
+
u_ior,
|
|
516
|
+
u_specularFactor,
|
|
517
|
+
u_specularColorFactor,
|
|
518
|
+
u_sheenColorFactor,
|
|
519
|
+
u_sheenRoughnessFactor,
|
|
520
|
+
u_anisotropyStrength,
|
|
521
|
+
u_anisotropyRotation,
|
|
522
|
+
u_iridescenceFactor,
|
|
523
|
+
u_iridescenceIor,
|
|
524
|
+
u_iridescenceThicknessMinimum,
|
|
525
|
+
u_iridescenceThicknessMaximum,
|
|
526
|
+
u_dispersion
|
|
527
|
+
);
|
|
528
|
+
float environmentHemi = mix(0.35, 1.0, clamp(normal.y * 0.5 + 0.5, 0.0, 1.0));
|
|
529
|
+
vec3 ambientEnvironment = u_environmentColor * u_environmentIntensity * environmentHemi;
|
|
530
|
+
float proceduralEnvironmentWeight = step(0.0001, u_environmentMapIntensity);
|
|
531
|
+
float skyBlend = clamp(normal.y * 0.5 + 0.5, 0.0, 1.0);
|
|
532
|
+
float horizonBlend = 1.0 - abs(normal.y);
|
|
533
|
+
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
534
|
+
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
535
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
536
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
537
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
538
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
539
|
+
// separate physical contributions, so they sum.
|
|
540
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
541
|
+
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
542
|
+
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
543
|
+
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
544
|
+
environmentDiffuse = mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
545
|
+
vec3 reflectionDirection = reflect(-viewDirection, normal);
|
|
546
|
+
float roughness = clamp(u_roughness, 0.0, 1.0);
|
|
547
|
+
float reflectionBand = pow(clamp(reflectionDirection.y * 0.5 + 0.5, 0.0, 1.0), mix(18.0, 2.0, roughness));
|
|
548
|
+
float roughEnvironmentFloor = mix(0.04, 0.38, roughness);
|
|
549
|
+
float proceduralSpecularResponse = max(reflectionBand, roughEnvironmentFloor);
|
|
550
|
+
vec3 proceduralSpecular = u_environmentSpecularColor * u_environmentSpecularIntensity * proceduralSpecularResponse * proceduralEnvironmentWeight;
|
|
551
|
+
float environmentLod = roughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
552
|
+
vec3 sampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
553
|
+
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
554
|
+
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, roughness)).rg;
|
|
555
|
+
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, roughness);
|
|
556
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(1.1, 0.85, roughness);
|
|
557
|
+
float clearcoatEnvironmentRoughness = clamp(u_clearcoatRoughnessFactor, 0.04, 1.0);
|
|
558
|
+
float clearcoatEnvironmentLod = clearcoatEnvironmentRoughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
559
|
+
vec3 clearcoatSampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, clearcoatEnvironmentLod)));
|
|
560
|
+
clearcoatSampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(1.1, 0.85, clearcoatEnvironmentRoughness);
|
|
561
|
+
vec3 extensionSpecular = proceduralSpecular + mix(sampledSpecular, clearcoatSampledSpecular, clamp(u_clearcoatFactor, 0.0, 1.0));
|
|
562
|
+
vec3 shaded = a3dPbrEnvironmentLightSplitSum(
|
|
563
|
+
normal,
|
|
564
|
+
viewDirection,
|
|
565
|
+
environmentDiffuse,
|
|
566
|
+
extensionSpecular,
|
|
567
|
+
mix(vec2(1.0, 0.0), brdfLut, step(0.0001, u_environmentBrdfLutEnabled)),
|
|
568
|
+
materialBase,
|
|
569
|
+
u_metallic,
|
|
570
|
+
u_roughness,
|
|
571
|
+
u_specularFactor,
|
|
572
|
+
u_specularColorFactor
|
|
573
|
+
) * mix(1.0, 0.18, clamp(u_anisotropyStrength, 0.0, 1.0)) + u_emissiveColor * u_emissiveStrength;
|
|
574
|
+
shaded += a3dPbrExtensionEnvironmentLight(
|
|
575
|
+
normal,
|
|
576
|
+
viewDirection,
|
|
577
|
+
proceduralSpecular + sampledSpecular,
|
|
578
|
+
u_clearcoatFactor,
|
|
579
|
+
u_clearcoatRoughnessFactor,
|
|
580
|
+
u_sheenColorFactor,
|
|
581
|
+
u_sheenRoughnessFactor,
|
|
582
|
+
u_anisotropyStrength,
|
|
583
|
+
u_anisotropyRotation,
|
|
584
|
+
u_iridescenceFactor,
|
|
585
|
+
u_iridescenceIor,
|
|
586
|
+
u_iridescenceThicknessMinimum,
|
|
587
|
+
u_iridescenceThicknessMaximum
|
|
588
|
+
);
|
|
589
|
+
float transmissionAmount = clamp(max(u_transmissionFactor, u_diffuseTransmissionFactor), 0.0, 1.0);
|
|
590
|
+
if (transmissionAmount > 0.0001 && sampledEnvironmentWeight > 0.0001) {
|
|
591
|
+
vec3 refractionDirection = refract(-viewDirection, normal, 1.0 / max(u_ior, 1.0));
|
|
592
|
+
refractionDirection = length(refractionDirection) > 0.0001 ? normalize(refractionDirection) : -reflectionDirection;
|
|
593
|
+
float parallaxStrength = clamp(u_transmissionParallaxStrength, 0.0, 1.0);
|
|
594
|
+
if (parallaxStrength > 0.0001) {
|
|
595
|
+
vec3 parallaxDirection = a3dPbrBoxProjectedDirection(v_worldPosition, refractionDirection, u_transmissionParallaxBoxMin, u_transmissionParallaxBoxMax);
|
|
596
|
+
refractionDirection = normalize(mix(refractionDirection, parallaxDirection, parallaxStrength));
|
|
597
|
+
}
|
|
598
|
+
float bounceCount = clamp(u_transmissionBounceCount, 0.0, 4.0);
|
|
599
|
+
float refractionLod = clamp(roughness + u_volumeThicknessFactor * 0.12 + bounceCount * 0.04 * parallaxStrength, 0.0, 1.0) * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
600
|
+
vec3 refractedEnvironment = a3dPbrBoundHdrTransmissionRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(refractionDirection, refractionLod)));
|
|
601
|
+
float volumeTravel = clamp((max(u_volumeThicknessFactor, 0.0) * (1.0 + bounceCount * 0.18 * parallaxStrength)) / max(u_volumeAttenuationDistance, 0.0001), 0.0, 16.0);
|
|
602
|
+
vec3 volumeTint = pow(clamp(u_volumeAttenuationColor, vec3(0.0001), vec3(1.0)), vec3(volumeTravel));
|
|
603
|
+
float causticEnergy = u_transmissionCausticStrength * parallaxStrength * transmissionAmount * pow(1.0 - roughness, 2.0) / (1.0 + bounceCount * 0.35);
|
|
604
|
+
float roughVolumeIorLift = mix(1.0, 1.45, clamp((u_ior - 1.0) / 1.5, 0.0, 1.0) * smoothstep(0.35, 0.95, roughness + u_volumeThicknessFactor * 0.2));
|
|
605
|
+
float fallbackEnvironmentTransmissionEnergy = mix(1.0, clamp(u_transmissionFallbackEnergy, 0.0, 1.0), transmissionAmount);
|
|
606
|
+
vec3 refractionRadiance = (refractedEnvironment + vec3(causticEnergy)) * volumeTint * u_environmentMapTextureIntensity * transmissionAmount * fallbackEnvironmentTransmissionEnergy * mix(0.9, 0.55, roughness) * roughVolumeIorLift;
|
|
607
|
+
shaded = mix(shaded, shaded * 0.72 + refractionRadiance, transmissionAmount * mix(0.08, 0.58, fallbackEnvironmentTransmissionEnergy));
|
|
608
|
+
}
|
|
609
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
610
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
611
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
612
|
+
for (int i = 0; i < 64; ++i) {
|
|
613
|
+
if (i >= count) break;
|
|
614
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
615
|
+
int baseIndex = lightIndex * 6;
|
|
616
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
617
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
618
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
619
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
620
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
621
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
622
|
+
float kind = directionKind.w;
|
|
623
|
+
if (kind > 2.5) {
|
|
624
|
+
shaded += a3dPbrRectAreaLight(
|
|
625
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
626
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
627
|
+
normal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
628
|
+
materialBase, u_metallic, u_roughness, u_specularFactor, u_specularColorFactor
|
|
629
|
+
);
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
vec3 lightDirection = -directionKind.xyz;
|
|
633
|
+
float attenuation = 1.0;
|
|
634
|
+
if (kind > 0.5) {
|
|
635
|
+
vec3 toLight = positionRange.xyz - v_worldPosition;
|
|
636
|
+
float distanceToLight = length(toLight);
|
|
637
|
+
lightDirection = distanceToLight > 0.0001 ? toLight / distanceToLight : -directionKind.xyz;
|
|
638
|
+
float range = max(positionRange.w, 0.0001);
|
|
639
|
+
float rangeFalloff = clamp(1.0 - pow(distanceToLight / range, 4.0), 0.0, 1.0);
|
|
640
|
+
rangeFalloff *= rangeFalloff;
|
|
641
|
+
attenuation = rangeFalloff / max(distanceToLight * distanceToLight, 1.0);
|
|
642
|
+
}
|
|
643
|
+
if (kind > 1.5) {
|
|
644
|
+
vec3 lightToFragment = normalize(v_worldPosition - positionRange.xyz);
|
|
645
|
+
float cone = dot(normalize(directionKind.xyz), lightToFragment);
|
|
646
|
+
float outer = cos(spotShadowLayer.x);
|
|
647
|
+
float inner = cos(spotShadowLayer.x * max(1.0 - spotShadowLayer.y, 0.001));
|
|
648
|
+
attenuation *= smoothstep(outer, inner, cone);
|
|
649
|
+
}
|
|
650
|
+
float directLightIntensity = colorIntensity.a * attenuation * mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z));
|
|
651
|
+
shaded += a3dPbrDirectLight(
|
|
652
|
+
normal,
|
|
653
|
+
viewDirection,
|
|
654
|
+
lightDirection,
|
|
655
|
+
colorIntensity.rgb,
|
|
656
|
+
directLightIntensity,
|
|
657
|
+
materialBase,
|
|
658
|
+
u_metallic,
|
|
659
|
+
u_roughness,
|
|
660
|
+
u_specularFactor,
|
|
661
|
+
u_specularColorFactor
|
|
662
|
+
) * mix(1.0, 0.18, clamp(u_anisotropyStrength, 0.0, 1.0));
|
|
663
|
+
shaded += a3dPbrExtensionDirectLight(
|
|
664
|
+
normal,
|
|
665
|
+
viewDirection,
|
|
666
|
+
lightDirection,
|
|
667
|
+
colorIntensity.rgb,
|
|
668
|
+
directLightIntensity,
|
|
669
|
+
u_clearcoatFactor,
|
|
670
|
+
u_clearcoatRoughnessFactor,
|
|
671
|
+
u_sheenColorFactor,
|
|
672
|
+
u_sheenRoughnessFactor,
|
|
673
|
+
u_anisotropyStrength,
|
|
674
|
+
u_anisotropyRotation,
|
|
675
|
+
u_iridescenceFactor,
|
|
676
|
+
u_iridescenceIor,
|
|
677
|
+
u_iridescenceThicknessMinimum,
|
|
678
|
+
u_iridescenceThicknessMaximum
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
float alpha = u_baseColor.a * v_vertexColor.a;
|
|
682
|
+
if (alpha < u_alphaCutoff) discard;
|
|
683
|
+
vec3 fogged = a3dApplyEnvironmentFog(max(shaded, vec3(0.0)), v_worldPosition);
|
|
684
|
+
outColor = vec4(a3dPbrEncodeOutput(fogged), alpha);
|
|
685
|
+
}
|
|
686
|
+
`
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
export function registerLeanDepthShader(library) {
|
|
690
|
+
library.register({
|
|
691
|
+
name: DEFAULT_DEPTH_SHADER_NAME,
|
|
692
|
+
marker: DEFAULT_DEPTH_SHADER_MARKER,
|
|
693
|
+
vertex: `#version 300 es
|
|
694
|
+
// ${DEFAULT_DEPTH_SHADER_MARKER}
|
|
695
|
+
precision highp float;
|
|
696
|
+
layout(location = 0) in vec3 a_position;
|
|
697
|
+
uniform mat4 u_modelViewProjection;
|
|
698
|
+
void main() {
|
|
699
|
+
gl_Position = u_modelViewProjection * vec4(a_position, 1.0);
|
|
700
|
+
}
|
|
701
|
+
`,
|
|
702
|
+
fragment: `#version 300 es
|
|
703
|
+
// ${DEFAULT_DEPTH_SHADER_MARKER}
|
|
704
|
+
precision highp float;
|
|
705
|
+
out vec4 outColor;
|
|
706
|
+
void main() {
|
|
707
|
+
outColor = vec4(vec3(gl_FragCoord.z), 1.0);
|
|
708
|
+
}
|
|
709
|
+
`
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
export function registerLeanEnvironmentBackgroundShader(library) {
|
|
713
|
+
library.register({
|
|
714
|
+
name: DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_NAME,
|
|
715
|
+
marker: DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_MARKER,
|
|
716
|
+
vertex: `#version 300 es
|
|
717
|
+
// ${DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_MARKER}
|
|
718
|
+
precision highp float;
|
|
719
|
+
layout(location = 0) in vec3 a_position;
|
|
720
|
+
out vec2 v_backgroundNdc;
|
|
721
|
+
void main() {
|
|
722
|
+
v_backgroundNdc = a_position.xy;
|
|
723
|
+
gl_Position = vec4(a_position.xy, 1.0, 1.0);
|
|
724
|
+
}
|
|
725
|
+
`,
|
|
726
|
+
fragment: `#version 300 es
|
|
727
|
+
// ${DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_MARKER}
|
|
728
|
+
precision highp float;
|
|
729
|
+
uniform sampler2D u_environmentBackgroundTexture;
|
|
730
|
+
uniform samplerCube u_environmentBackgroundCubeTexture;
|
|
731
|
+
uniform float u_environmentBackgroundProjection;
|
|
732
|
+
uniform float u_environmentBackgroundRotation;
|
|
733
|
+
uniform float u_environmentBackgroundIntensity;
|
|
734
|
+
uniform float u_environmentBackgroundEncoding;
|
|
735
|
+
uniform float u_outputColorSpace;
|
|
736
|
+
uniform mat4 u_environmentBackgroundInverseViewProjection;
|
|
737
|
+
in vec2 v_backgroundNdc;
|
|
738
|
+
out vec4 outColor;
|
|
739
|
+
vec2 a3dBackgroundEquirectUv(vec3 direction) {
|
|
740
|
+
vec3 d = normalize(direction);
|
|
741
|
+
float u = atan(d.z, d.x) / 6.28318530718 + 0.5;
|
|
742
|
+
float v = acos(clamp(d.y, -1.0, 1.0)) / 3.14159265359;
|
|
743
|
+
return vec2(fract(u), clamp(v, 0.0, 1.0));
|
|
744
|
+
}
|
|
745
|
+
vec3 a3dRotateBackgroundDirection(vec3 direction, float rotation) {
|
|
746
|
+
float angle = rotation * 6.28318530718;
|
|
747
|
+
float c = cos(angle);
|
|
748
|
+
float s = sin(angle);
|
|
749
|
+
vec3 d = normalize(direction);
|
|
750
|
+
return normalize(vec3(c * d.x - s * d.z, d.y, s * d.x + c * d.z));
|
|
751
|
+
}
|
|
752
|
+
vec3 a3dBackgroundDirectionFromNdc(vec2 ndc) {
|
|
753
|
+
vec4 nearPoint = u_environmentBackgroundInverseViewProjection * vec4(ndc, -1.0, 1.0);
|
|
754
|
+
vec4 farPoint = u_environmentBackgroundInverseViewProjection * vec4(ndc, 1.0, 1.0);
|
|
755
|
+
vec3 nearWorld = nearPoint.xyz / max(nearPoint.w, 0.00001);
|
|
756
|
+
vec3 farWorld = farPoint.xyz / max(farPoint.w, 0.00001);
|
|
757
|
+
return normalize(farWorld - nearWorld);
|
|
758
|
+
}
|
|
759
|
+
vec3 a3dBackgroundDecodeRgbe(vec4 encodedSample) {
|
|
760
|
+
float exponent = encodedSample.a * 255.0;
|
|
761
|
+
float scale = exponent <= 0.0 ? 0.0 : exp2(exponent - 128.0) * (255.0 / 256.0);
|
|
762
|
+
return max(encodedSample.rgb * scale, vec3(0.0));
|
|
763
|
+
}
|
|
764
|
+
vec3 a3dBackgroundDecode(vec4 encodedSample) {
|
|
765
|
+
if (u_environmentBackgroundEncoding > 1.5) return a3dBackgroundDecodeRgbe(encodedSample);
|
|
766
|
+
return max(encodedSample.rgb, vec3(0.0));
|
|
767
|
+
}
|
|
768
|
+
vec3 a3dBackgroundEncodeOutput(vec3 linearColor) {
|
|
769
|
+
vec3 color = max(linearColor, vec3(0.0));
|
|
770
|
+
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
771
|
+
vec3 srgb = pow(filmic, vec3(1.0 / 2.2));
|
|
772
|
+
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
773
|
+
}
|
|
774
|
+
void main() {
|
|
775
|
+
vec3 direction = a3dRotateBackgroundDirection(a3dBackgroundDirectionFromNdc(v_backgroundNdc), u_environmentBackgroundRotation);
|
|
776
|
+
vec4 encodedSample = vec4(0.0, 0.0, 0.0, 1.0);
|
|
777
|
+
if (u_environmentBackgroundProjection > 1.5) {
|
|
778
|
+
encodedSample = texture(u_environmentBackgroundCubeTexture, direction);
|
|
779
|
+
} else {
|
|
780
|
+
encodedSample = texture(u_environmentBackgroundTexture, a3dBackgroundEquirectUv(direction));
|
|
781
|
+
}
|
|
782
|
+
vec3 color = a3dBackgroundDecode(encodedSample) * max(u_environmentBackgroundIntensity, 0.0);
|
|
783
|
+
outColor = vec4(a3dBackgroundEncodeOutput(color), 1.0);
|
|
784
|
+
}
|
|
785
|
+
`
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
export function createLeanCoreShaderLibrary() {
|
|
789
|
+
const library = new ShaderLibrary();
|
|
790
|
+
validateShaderChunks();
|
|
791
|
+
for (const chunk of SHADER_CHUNKS) {
|
|
792
|
+
library.registerChunk(chunk.name, chunk.source);
|
|
793
|
+
}
|
|
794
|
+
registerLeanUnlitShader(library);
|
|
795
|
+
registerLeanPbrShader(library);
|
|
796
|
+
registerLeanDepthShader(library);
|
|
797
|
+
registerLeanEnvironmentBackgroundShader(library);
|
|
798
|
+
return library;
|
|
799
|
+
}
|
|
800
|
+
//# sourceMappingURL=ShaderLibraryCore.js.map
|