@flighthq/scene3d-gl 0.2.1-next.840.857425c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/anisotropyPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/anisotropyPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/anisotropyPbrGlMeshMaterialRenderer.js +45 -0
- package/dist/anisotropyPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.js +102 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.js.map +1 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.js +45 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/customShaderGlMeshMaterialRenderer.d.ts +6 -0
- package/dist/customShaderGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/customShaderGlMeshMaterialRenderer.js +136 -0
- package/dist/customShaderGlMeshMaterialRenderer.js.map +1 -0
- package/dist/depthGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/depthGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/depthGlMeshMaterialRenderer.js +36 -0
- package/dist/depthGlMeshMaterialRenderer.js.map +1 -0
- package/dist/drawGlScene3D.d.ts +3 -0
- package/dist/drawGlScene3D.d.ts.map +1 -0
- package/dist/drawGlScene3D.js +251 -0
- package/dist/drawGlScene3D.js.map +1 -0
- package/dist/emissiveGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/emissiveGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/emissiveGlMeshMaterialRenderer.js +49 -0
- package/dist/emissiveGlMeshMaterialRenderer.js.map +1 -0
- package/dist/enableGlScene3DColorSpaceGuards.d.ts +4 -0
- package/dist/enableGlScene3DColorSpaceGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DColorSpaceGuards.js +22 -0
- package/dist/enableGlScene3DColorSpaceGuards.js.map +1 -0
- package/dist/enableGlScene3DCustomShaderGuards.d.ts +4 -0
- package/dist/enableGlScene3DCustomShaderGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DCustomShaderGuards.js +71 -0
- package/dist/enableGlScene3DCustomShaderGuards.js.map +1 -0
- package/dist/enableGlScene3DDeformGuards.d.ts +4 -0
- package/dist/enableGlScene3DDeformGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DDeformGuards.js +42 -0
- package/dist/enableGlScene3DDeformGuards.js.map +1 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.d.ts +4 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.js +21 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.js.map +1 -0
- package/dist/explainGlScene3DForwardLightSelection.d.ts +3 -0
- package/dist/explainGlScene3DForwardLightSelection.d.ts.map +1 -0
- package/dist/explainGlScene3DForwardLightSelection.js +19 -0
- package/dist/explainGlScene3DForwardLightSelection.js.map +1 -0
- package/dist/glClassicPrelude.d.ts +9 -0
- package/dist/glClassicPrelude.d.ts.map +1 -0
- package/dist/glClassicPrelude.js +288 -0
- package/dist/glClassicPrelude.js.map +1 -0
- package/dist/glDebugPrelude.d.ts +9 -0
- package/dist/glDebugPrelude.d.ts.map +1 -0
- package/dist/glDebugPrelude.js +143 -0
- package/dist/glDebugPrelude.js.map +1 -0
- package/dist/glEnvironmentCube.d.ts +5 -0
- package/dist/glEnvironmentCube.d.ts.map +1 -0
- package/dist/glEnvironmentCube.js +65 -0
- package/dist/glEnvironmentCube.js.map +1 -0
- package/dist/glEnvironmentIblBake.d.ts +4 -0
- package/dist/glEnvironmentIblBake.d.ts.map +1 -0
- package/dist/glEnvironmentIblBake.js +365 -0
- package/dist/glEnvironmentIblBake.js.map +1 -0
- package/dist/glEnvironmentSkybox.d.ts +3 -0
- package/dist/glEnvironmentSkybox.d.ts.map +1 -0
- package/dist/glEnvironmentSkybox.js +95 -0
- package/dist/glEnvironmentSkybox.js.map +1 -0
- package/dist/glLitProgram.d.ts +5 -0
- package/dist/glLitProgram.d.ts.map +1 -0
- package/dist/glLitProgram.js +211 -0
- package/dist/glLitProgram.js.map +1 -0
- package/dist/glMatcapPrelude.d.ts +8 -0
- package/dist/glMatcapPrelude.d.ts.map +1 -0
- package/dist/glMatcapPrelude.js +118 -0
- package/dist/glMatcapPrelude.js.map +1 -0
- package/dist/glMeshMaterialRegistry.d.ts +5 -0
- package/dist/glMeshMaterialRegistry.d.ts.map +1 -0
- package/dist/glMeshMaterialRegistry.js +29 -0
- package/dist/glMeshMaterialRegistry.js.map +1 -0
- package/dist/glMeshProgram.d.ts +14 -0
- package/dist/glMeshProgram.d.ts.map +1 -0
- package/dist/glMeshProgram.js +193 -0
- package/dist/glMeshProgram.js.map +1 -0
- package/dist/glMeshUpload.d.ts +4 -0
- package/dist/glMeshUpload.d.ts.map +1 -0
- package/dist/glMeshUpload.js +190 -0
- package/dist/glMeshUpload.js.map +1 -0
- package/dist/glParticleEmitter3D.d.ts +4 -0
- package/dist/glParticleEmitter3D.d.ts.map +1 -0
- package/dist/glParticleEmitter3D.js +342 -0
- package/dist/glParticleEmitter3D.js.map +1 -0
- package/dist/glPbrPrelude.d.ts +8 -0
- package/dist/glPbrPrelude.d.ts.map +1 -0
- package/dist/glPbrPrelude.js +569 -0
- package/dist/glPbrPrelude.js.map +1 -0
- package/dist/glPbrProgramCache.d.ts +4 -0
- package/dist/glPbrProgramCache.d.ts.map +1 -0
- package/dist/glPbrProgramCache.js +63 -0
- package/dist/glPbrProgramCache.js.map +1 -0
- package/dist/glPbrStandardBlock.d.ts +13 -0
- package/dist/glPbrStandardBlock.d.ts.map +1 -0
- package/dist/glPbrStandardBlock.js +107 -0
- package/dist/glPbrStandardBlock.js.map +1 -0
- package/dist/glScene3DRuntime.d.ts +5 -0
- package/dist/glScene3DRuntime.d.ts.map +1 -0
- package/dist/glScene3DRuntime.js +99 -0
- package/dist/glScene3DRuntime.js.map +1 -0
- package/dist/glScene3DTestHelper.d.ts +20 -0
- package/dist/glScene3DTestHelper.d.ts.map +1 -0
- package/dist/glScene3DTestHelper.js +178 -0
- package/dist/glScene3DTestHelper.js.map +1 -0
- package/dist/glScene3DTime.d.ts +4 -0
- package/dist/glScene3DTime.d.ts.map +1 -0
- package/dist/glScene3DTime.js +18 -0
- package/dist/glScene3DTime.js.map +1 -0
- package/dist/glShadedBuiltInModifiers.d.ts +11 -0
- package/dist/glShadedBuiltInModifiers.d.ts.map +1 -0
- package/dist/glShadedBuiltInModifiers.js +386 -0
- package/dist/glShadedBuiltInModifiers.js.map +1 -0
- package/dist/glShadedModifierSnippet.d.ts +4 -0
- package/dist/glShadedModifierSnippet.d.ts.map +1 -0
- package/dist/glShadedModifierSnippet.js +24 -0
- package/dist/glShadedModifierSnippet.js.map +1 -0
- package/dist/glShadedPrelude.d.ts +5 -0
- package/dist/glShadedPrelude.d.ts.map +1 -0
- package/dist/glShadedPrelude.js +393 -0
- package/dist/glShadedPrelude.js.map +1 -0
- package/dist/glShadowMap.d.ts +3 -0
- package/dist/glShadowMap.d.ts.map +1 -0
- package/dist/glShadowMap.js +150 -0
- package/dist/glShadowMap.js.map +1 -0
- package/dist/glToonPrelude.d.ts +7 -0
- package/dist/glToonPrelude.d.ts.map +1 -0
- package/dist/glToonPrelude.js +172 -0
- package/dist/glToonPrelude.js.map +1 -0
- package/dist/glUnlitPrelude.d.ts +9 -0
- package/dist/glUnlitPrelude.d.ts.map +1 -0
- package/dist/glUnlitPrelude.js +160 -0
- package/dist/glUnlitPrelude.js.map +1 -0
- package/dist/glWireframePrelude.d.ts +6 -0
- package/dist/glWireframePrelude.d.ts.map +1 -0
- package/dist/glWireframePrelude.js +56 -0
- package/dist/glWireframePrelude.js.map +1 -0
- package/dist/glWireframeUpload.d.ts +4 -0
- package/dist/glWireframeUpload.d.ts.map +1 -0
- package/dist/glWireframeUpload.js +85 -0
- package/dist/glWireframeUpload.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.js +54 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/lambertGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/lambertGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/lambertGlMeshMaterialRenderer.js +70 -0
- package/dist/lambertGlMeshMaterialRenderer.js.map +1 -0
- package/dist/matcapGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/matcapGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/matcapGlMeshMaterialRenderer.js +49 -0
- package/dist/matcapGlMeshMaterialRenderer.js.map +1 -0
- package/dist/normalGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/normalGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/normalGlMeshMaterialRenderer.js +39 -0
- package/dist/normalGlMeshMaterialRenderer.js.map +1 -0
- package/dist/phongGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/phongGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/phongGlMeshMaterialRenderer.js +90 -0
- package/dist/phongGlMeshMaterialRenderer.js.map +1 -0
- package/dist/prepareGlScene3DForwardLights.d.ts +3 -0
- package/dist/prepareGlScene3DForwardLights.d.ts.map +1 -0
- package/dist/prepareGlScene3DForwardLights.js +117 -0
- package/dist/prepareGlScene3DForwardLights.js.map +1 -0
- package/dist/presentGlScene3D.d.ts +3 -0
- package/dist/presentGlScene3D.d.ts.map +1 -0
- package/dist/presentGlScene3D.js +21 -0
- package/dist/presentGlScene3D.js.map +1 -0
- package/dist/registerStandardPbrGlMaterial.d.ts +3 -0
- package/dist/registerStandardPbrGlMaterial.d.ts.map +1 -0
- package/dist/registerStandardPbrGlMaterial.js +11 -0
- package/dist/registerStandardPbrGlMaterial.js.map +1 -0
- package/dist/shadedGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/shadedGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/shadedGlMeshMaterialRenderer.js +135 -0
- package/dist/shadedGlMeshMaterialRenderer.js.map +1 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.js +54 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.js +121 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/specularPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/specularPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/specularPbrGlMeshMaterialRenderer.js +55 -0
- package/dist/specularPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/standardPbrGlMeshMaterialRenderer.d.ts +3 -0
- package/dist/standardPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/standardPbrGlMeshMaterialRenderer.js +35 -0
- package/dist/standardPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.js +57 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/toonGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/toonGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/toonGlMeshMaterialRenderer.js +81 -0
- package/dist/toonGlMeshMaterialRenderer.js.map +1 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.js +62 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/unlitGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/unlitGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/unlitGlMeshMaterialRenderer.js +61 -0
- package/dist/unlitGlMeshMaterialRenderer.js.map +1 -0
- package/dist/vertexColorGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/vertexColorGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/vertexColorGlMeshMaterialRenderer.js +54 -0
- package/dist/vertexColorGlMeshMaterialRenderer.js.map +1 -0
- package/dist/wireframeGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/wireframeGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/wireframeGlMeshMaterialRenderer.js +50 -0
- package/dist/wireframeGlMeshMaterialRenderer.js.map +1 -0
- package/package.json +58 -0
- package/src/anisotropyPbrGlMeshMaterialRenderer.test.ts +86 -0
- package/src/blinnPhongGlMeshMaterialRenderer.test.ts +94 -0
- package/src/clearcoatPbrGlMeshMaterialRenderer.test.ts +81 -0
- package/src/customShaderGlMeshMaterialRenderer.test.ts +169 -0
- package/src/depthGlMeshMaterialRenderer.test.ts +69 -0
- package/src/drawGlScene3D.test.ts +304 -0
- package/src/emissiveGlMeshMaterialRenderer.test.ts +60 -0
- package/src/enableGlScene3DColorSpaceGuards.test.ts +63 -0
- package/src/enableGlScene3DCustomShaderGuards.test.ts +85 -0
- package/src/enableGlScene3DDeformGuards.test.ts +98 -0
- package/src/enableGlScene3DForwardLightSelectionGuards.test.ts +84 -0
- package/src/explainGlScene3DForwardLightSelection.test.ts +32 -0
- package/src/glClassicPrelude.test.ts +214 -0
- package/src/glDebugPrelude.test.ts +94 -0
- package/src/glEnvironmentCube.test.ts +71 -0
- package/src/glEnvironmentIblBake.test.ts +31 -0
- package/src/glEnvironmentSkybox.test.ts +24 -0
- package/src/glLitProgram.test.ts +181 -0
- package/src/glMatcapPrelude.test.ts +74 -0
- package/src/glMeshMaterialRegistry.test.ts +52 -0
- package/src/glMeshProgram.test.ts +406 -0
- package/src/glMeshUpload.test.ts +311 -0
- package/src/glParticleEmitter3D.test.ts +280 -0
- package/src/glPbrPrelude.test.ts +178 -0
- package/src/glPbrProgramCache.test.ts +116 -0
- package/src/glPbrStandardBlock.test.ts +85 -0
- package/src/glScene3DRuntime.test.ts +108 -0
- package/src/glScene3DTime.test.ts +31 -0
- package/src/glShadedBuiltInModifiers.test.ts +377 -0
- package/src/glShadedModifierSnippet.test.ts +46 -0
- package/src/glShadedPrelude.test.ts +177 -0
- package/src/glShadowMap.test.ts +219 -0
- package/src/glToonPrelude.test.ts +118 -0
- package/src/glUnlitPrelude.test.ts +156 -0
- package/src/glWireframePrelude.test.ts +46 -0
- package/src/glWireframeUpload.test.ts +50 -0
- package/src/iridescencePbrGlMeshMaterialRenderer.test.ts +86 -0
- package/src/lambertGlMeshMaterialRenderer.test.ts +92 -0
- package/src/matcapGlMeshMaterialRenderer.test.ts +70 -0
- package/src/normalGlMeshMaterialRenderer.test.ts +69 -0
- package/src/phongGlMeshMaterialRenderer.test.ts +94 -0
- package/src/prepareGlScene3DForwardLights.test.ts +106 -0
- package/src/presentGlScene3D.test.ts +98 -0
- package/src/registerStandardPbrGlMaterial.test.ts +14 -0
- package/src/shadedGlMeshMaterialRenderer.test.ts +106 -0
- package/src/sheenPbrGlMeshMaterialRenderer.test.ts +83 -0
- package/src/specularGlossinessPbrGlMeshMaterialRenderer.test.ts +96 -0
- package/src/specularPbrGlMeshMaterialRenderer.test.ts +83 -0
- package/src/standardPbrGlMeshMaterialRenderer.test.ts +88 -0
- package/src/subsurfacePbrGlMeshMaterialRenderer.test.ts +86 -0
- package/src/toonGlMeshMaterialRenderer.test.ts +92 -0
- package/src/transmissionVolumePbrGlMeshMaterialRenderer.test.ts +93 -0
- package/src/unlitGlMeshMaterialRenderer.test.ts +88 -0
- package/src/vertexColorGlMeshMaterialRenderer.test.ts +60 -0
- package/src/wireframeGlMeshMaterialRenderer.test.ts +69 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { createModifierRegistry, getModifierDefineKey, orderModifierStack, resolveModifier } from '@flighthq/shading';
|
|
2
|
+
import { MAX_FORWARD_LIGHTS, ModifierSlot } from '@flighthq/types';
|
|
3
|
+
import { GL_MESH_LIGHT_BLOCK_GLSL, resolveGlLitLocations } from './glLitProgram';
|
|
4
|
+
import { GL_SKIN_VERTEX_DECLARATIONS_GLSL, GL_UV_TRANSFORM_VERTEX_GLSL, compileGlProgram, ensureGlScene3DProgram, } from './glMeshProgram';
|
|
5
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
6
|
+
// The stable program-cache key for a ShadedMaterial variant: the base feature flags joined with the
|
|
7
|
+
// modifier stack's define-key. Two materials sharing both the same base flags AND the same modifier
|
|
8
|
+
// feature-set produce the same key and share one compiled program (and batch together); a different
|
|
9
|
+
// map set OR a different modifier feature-set breaks the batch. `modifierDefineKey` comes from
|
|
10
|
+
// @flighthq/shading's getModifierDefineKey, so cross-slot authoring order never changes it.
|
|
11
|
+
export function buildGlShadedCacheKey(key, modifierDefineKey) {
|
|
12
|
+
const base = `${key.alphaMaskEnabled ? 'm' : '-'}${key.hasDiffuseMap ? 'd' : '-'}${key.hasSpecularMap ? 's' : '-'}${key.hasNormalMap ? 'n' : '-'}${key.hasUvTransform ? 'u' : '-'}${key.hasSkin ? 'k' : '-'}`;
|
|
13
|
+
return `shaded:${base}|${modifierDefineKey}`;
|
|
14
|
+
}
|
|
15
|
+
// Compiles the ShadedMaterial uber-shader for a base key and an ORDERED modifier stack: assembles the
|
|
16
|
+
// base lit source (reusing GL_MESH_LIGHT_BLOCK_GLSL for lighting — no second light loop) with each
|
|
17
|
+
// modifier's GLSL injected at its slot hook, links it, and resolves the base + time uniform
|
|
18
|
+
// locations. Pure GL work — no caching — used by ensureGlShadedProgram. Throws on a compile/link
|
|
19
|
+
// failure (a programmer error: a malformed base or modifier snippet), not an expected runtime case.
|
|
20
|
+
export function compileGlShadedProgram(gl, key, orderedModifiers, registry) {
|
|
21
|
+
const defineSource = buildGlShadedDefineSource(key);
|
|
22
|
+
// The skin GLSL is vertex-only (its `in` attributes are illegal in a fragment shader), so it is
|
|
23
|
+
// spliced into the vertex source alone, never the fragment. The Vertex-slot modifiers are likewise
|
|
24
|
+
// vertex-only — they deform the geometry — so they inject into the vertex body, not the fragment.
|
|
25
|
+
const vertexSource = defineSource +
|
|
26
|
+
(key.hasSkin ? GL_SKIN_VERTEX_DECLARATIONS_GLSL : '') +
|
|
27
|
+
assembleGlShadedVertexBody(orderedModifiers, registry);
|
|
28
|
+
const fragmentSource = defineSource + assembleGlShadedFragmentBody(orderedModifiers, registry);
|
|
29
|
+
const program = compileGlProgram(gl, vertexSource, fragmentSource);
|
|
30
|
+
return {
|
|
31
|
+
...resolveGlLitLocations(gl, program),
|
|
32
|
+
program,
|
|
33
|
+
locAlphaCutoff: gl.getUniformLocation(program, 'u_alphaCutoff'),
|
|
34
|
+
locDiffuse: gl.getUniformLocation(program, 'u_diffuse'),
|
|
35
|
+
locDiffuseMap: gl.getUniformLocation(program, 'u_diffuseMap'),
|
|
36
|
+
locJointTexture: gl.getUniformLocation(program, 'u_jointTexture'),
|
|
37
|
+
locModel: gl.getUniformLocation(program, 'u_model'),
|
|
38
|
+
locNormalMap: gl.getUniformLocation(program, 'u_normalMap'),
|
|
39
|
+
locNormalMatrix: gl.getUniformLocation(program, 'u_normalMatrix'),
|
|
40
|
+
locNormalScale: gl.getUniformLocation(program, 'u_normalScale'),
|
|
41
|
+
locShininess: gl.getUniformLocation(program, 'u_shininess'),
|
|
42
|
+
locSpecular: gl.getUniformLocation(program, 'u_specular'),
|
|
43
|
+
locSpecularMap: gl.getUniformLocation(program, 'u_specularMap'),
|
|
44
|
+
locTime: gl.getUniformLocation(program, 'u_time'),
|
|
45
|
+
locViewProjection: gl.getUniformLocation(program, 'u_viewProjection'),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Resolves the ShadedMaterial program for a base key and modifier stack, compiling and caching it on
|
|
49
|
+
// first use under the `shaded:` family namespace. Orders the stack and computes its define-key from
|
|
50
|
+
// this state's modifier-snippet registry (so the cache key captures every compile-time modifier
|
|
51
|
+
// variant), then keys the shared scene program cache by base-key + modifier-define-key — each variant
|
|
52
|
+
// compiles at most once per state and reused every frame.
|
|
53
|
+
export function ensureGlShadedProgram(state, key, modifiers) {
|
|
54
|
+
// A null registry means no modifier snippet was ever registered (the lazy-allocation default); the
|
|
55
|
+
// shared empty registry then yields the coarse bare-kind define-key and no modifier GLSL — the same
|
|
56
|
+
// result an allocated-but-empty registry gives — without allocating on this per-bind path.
|
|
57
|
+
const registry = getGlScene3DRuntime(state).modifierSnippetRegistry ?? EMPTY_MODIFIER_REGISTRY;
|
|
58
|
+
const ordered = orderModifierStack(modifiers);
|
|
59
|
+
// Fold the render-state skinned-run flag into the variant so a skinned draw of an otherwise-identical
|
|
60
|
+
// material compiles + caches its own HAS_SKIN program, without the material renderer knowing.
|
|
61
|
+
const fullKey = {
|
|
62
|
+
...key,
|
|
63
|
+
hasSkin: getGlScene3DRuntime(state).activeSkinnedRun,
|
|
64
|
+
};
|
|
65
|
+
const cacheKey = buildGlShadedCacheKey(fullKey, getModifierDefineKey(modifiers, registry));
|
|
66
|
+
return ensureGlScene3DProgram(state, cacheKey, (gl) => compileGlShadedProgram(gl, fullKey, ordered, registry));
|
|
67
|
+
}
|
|
68
|
+
// Assembles the ShadedMaterial fragment body for an ordered modifier stack: each FRAGMENT-slot
|
|
69
|
+
// modifier's declarations are collected at the top, and each contribution is injected at the hook for
|
|
70
|
+
// its slot (Normal perturbs the normal before lighting, Diffuse/Specular adjust the surface terms,
|
|
71
|
+
// Emissive adds self-illumination, Effect post-processes the shaded radiance). Vertex-slot modifiers
|
|
72
|
+
// are skipped here — they inject into the vertex body (assembleGlShadedVertexBody). A modifier whose
|
|
73
|
+
// kind has no registered GL snippet contributes nothing. An empty stack leaves every hook empty,
|
|
74
|
+
// yielding the lean plain-ShadedMaterial variant that pays nothing for modifiers it does not carry.
|
|
75
|
+
function assembleGlShadedFragmentBody(orderedModifiers, registry) {
|
|
76
|
+
let declarations = '';
|
|
77
|
+
let normal = '';
|
|
78
|
+
let diffuse = '';
|
|
79
|
+
let specular = '';
|
|
80
|
+
let emissive = '';
|
|
81
|
+
let effect = '';
|
|
82
|
+
for (let index = 0; index < orderedModifiers.length; index++) {
|
|
83
|
+
const modifier = orderedModifiers[index];
|
|
84
|
+
const snippet = resolveModifier(registry, modifier.kind);
|
|
85
|
+
if (snippet === null || snippet.slot === ModifierSlot.Vertex)
|
|
86
|
+
continue;
|
|
87
|
+
if (snippet.declarations !== undefined)
|
|
88
|
+
declarations += `${snippet.declarations(modifier, index)}\n`;
|
|
89
|
+
const contribution = `${snippet.contribution(modifier, index)}\n`;
|
|
90
|
+
if (snippet.slot === ModifierSlot.Normal)
|
|
91
|
+
normal += contribution;
|
|
92
|
+
else if (snippet.slot === ModifierSlot.Diffuse)
|
|
93
|
+
diffuse += contribution;
|
|
94
|
+
else if (snippet.slot === ModifierSlot.Specular)
|
|
95
|
+
specular += contribution;
|
|
96
|
+
else if (snippet.slot === ModifierSlot.Emissive)
|
|
97
|
+
emissive += contribution;
|
|
98
|
+
else if (snippet.slot === ModifierSlot.Effect)
|
|
99
|
+
effect += contribution;
|
|
100
|
+
}
|
|
101
|
+
return SHADED_FRAGMENT_TEMPLATE.replace('//@DECLARATIONS', dedupeGlShadedDeclarations(declarations))
|
|
102
|
+
.replace('//@NORMAL', normal)
|
|
103
|
+
.replace('//@DIFFUSE', diffuse)
|
|
104
|
+
.replace('//@SPECULAR', specular)
|
|
105
|
+
.replace('//@EMISSIVE', emissive)
|
|
106
|
+
.replace('//@EFFECT', effect);
|
|
107
|
+
}
|
|
108
|
+
// Assembles the ShadedMaterial vertex body for an ordered modifier stack: only the VERTEX-slot
|
|
109
|
+
// modifiers contribute here (they deform the geometry). Their declarations go at the top-level
|
|
110
|
+
// //@VERTEX_DECLARATIONS hook and their contributions at the //@VERTEX hook — after localPosition/
|
|
111
|
+
// localNormal are computed (post-skin) but before the model transform, so displacement composes with
|
|
112
|
+
// skinning. Non-vertex slots are skipped (they inject into the fragment body). An empty vertex set
|
|
113
|
+
// leaves both hooks empty, yielding the plain vertex program.
|
|
114
|
+
function assembleGlShadedVertexBody(orderedModifiers, registry) {
|
|
115
|
+
let declarations = '';
|
|
116
|
+
let vertex = '';
|
|
117
|
+
for (let index = 0; index < orderedModifiers.length; index++) {
|
|
118
|
+
const modifier = orderedModifiers[index];
|
|
119
|
+
const snippet = resolveModifier(registry, modifier.kind);
|
|
120
|
+
if (snippet === null || snippet.slot !== ModifierSlot.Vertex)
|
|
121
|
+
continue;
|
|
122
|
+
if (snippet.declarations !== undefined)
|
|
123
|
+
declarations += `${snippet.declarations(modifier, index)}\n`;
|
|
124
|
+
vertex += `${snippet.contribution(modifier, index)}\n`;
|
|
125
|
+
}
|
|
126
|
+
return SHADED_VERTEX_BODY.replace('//@VERTEX_DECLARATIONS', dedupeGlShadedDeclarations(declarations)).replace('//@VERTEX', vertex);
|
|
127
|
+
}
|
|
128
|
+
// Collapses duplicate declaration lines in an assembled modifier declaration block, preserving the
|
|
129
|
+
// order of first appearance and dropping later exact repeats. Per-instance uniforms are unique (each
|
|
130
|
+
// name carries its stack-index suffix, e.g. `u_fogColor_2`), so they always survive; the SHARED
|
|
131
|
+
// un-suffixed lines a snippet declares — the IBL environment samplers an env-reflect modifier reads,
|
|
132
|
+
// or the value-noise helper a procedural dissolve declares — collapse to one when two modifiers of the
|
|
133
|
+
// same kind appear in one stack, avoiding a GLSL redefinition error. Blank lines are kept verbatim so
|
|
134
|
+
// helper-function bodies (whose braces span lines) stay intact.
|
|
135
|
+
function dedupeGlShadedDeclarations(declarations) {
|
|
136
|
+
const seen = new Set();
|
|
137
|
+
let result = '';
|
|
138
|
+
for (const line of declarations.split('\n')) {
|
|
139
|
+
const trimmed = line.trim();
|
|
140
|
+
const isSharedDeclaration = trimmed.startsWith('uniform ') && !/_\d+\b/.test(trimmed);
|
|
141
|
+
if (isSharedDeclaration) {
|
|
142
|
+
if (seen.has(trimmed))
|
|
143
|
+
continue;
|
|
144
|
+
seen.add(trimmed);
|
|
145
|
+
}
|
|
146
|
+
result += `${line}\n`;
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
// Builds the leading "#version 300 es\n#define ..." block shared by the vertex and fragment stages
|
|
151
|
+
// for a base key. Modifier variants are NOT #defines — they are injected as GLSL by
|
|
152
|
+
// assembleGlShadedFragmentBody — so only the base map/alpha flags appear here.
|
|
153
|
+
function buildGlShadedDefineSource(key) {
|
|
154
|
+
let defines = `#version 300 es\n#define MAX_FORWARD_LIGHTS ${MAX_FORWARD_LIGHTS}\n`;
|
|
155
|
+
if (key.alphaMaskEnabled)
|
|
156
|
+
defines += '#define ALPHA_MASK\n';
|
|
157
|
+
if (key.hasDiffuseMap)
|
|
158
|
+
defines += '#define HAS_DIFFUSE_MAP\n';
|
|
159
|
+
if (key.hasSpecularMap)
|
|
160
|
+
defines += '#define HAS_SPECULAR_MAP\n';
|
|
161
|
+
if (key.hasNormalMap)
|
|
162
|
+
defines += '#define HAS_NORMAL_MAP\n';
|
|
163
|
+
if (key.hasUvTransform)
|
|
164
|
+
defines += '#define HAS_UV_TRANSFORM\n';
|
|
165
|
+
if (key.hasSkin)
|
|
166
|
+
defines += '#define HAS_SKIN\n';
|
|
167
|
+
return defines;
|
|
168
|
+
}
|
|
169
|
+
const SHADED_VERTEX_BODY = `
|
|
170
|
+
layout(location = 0) in vec3 a_position;
|
|
171
|
+
layout(location = 1) in vec3 a_normal;
|
|
172
|
+
layout(location = 2) in vec4 a_tangent;
|
|
173
|
+
layout(location = 3) in vec2 a_uv0;
|
|
174
|
+
|
|
175
|
+
uniform mat4 u_viewProjection;
|
|
176
|
+
uniform mat4 u_model;
|
|
177
|
+
uniform mat3 u_normalMatrix;
|
|
178
|
+
uniform float u_time;
|
|
179
|
+
${GL_UV_TRANSFORM_VERTEX_GLSL}
|
|
180
|
+
out vec3 v_worldPosition;
|
|
181
|
+
out vec3 v_normal;
|
|
182
|
+
out vec4 v_tangent;
|
|
183
|
+
out vec2 v_uv0;
|
|
184
|
+
|
|
185
|
+
//@VERTEX_DECLARATIONS
|
|
186
|
+
|
|
187
|
+
void main() {
|
|
188
|
+
#ifdef HAS_SKIN
|
|
189
|
+
mat4 skin = skinMatrix();
|
|
190
|
+
vec4 localPosition = skin * vec4(a_position, 1.0);
|
|
191
|
+
vec3 localNormal = mat3(skin) * a_normal;
|
|
192
|
+
vec3 localTangent = mat3(skin) * a_tangent.xyz;
|
|
193
|
+
#else
|
|
194
|
+
vec4 localPosition = vec4(a_position, 1.0);
|
|
195
|
+
vec3 localNormal = a_normal;
|
|
196
|
+
vec3 localTangent = a_tangent.xyz;
|
|
197
|
+
#endif
|
|
198
|
+
vec2 vertexUv = a_uv0;
|
|
199
|
+
|
|
200
|
+
// Vertex slot: read/write \`localPosition\` (the pre-model local vertex) and \`localNormal\`; the
|
|
201
|
+
// procedural cases scroll by \`u_time\` and read \`vertexUv\` (the raw uv, before the uv transform).
|
|
202
|
+
//@VERTEX
|
|
203
|
+
|
|
204
|
+
vec4 worldPosition = u_model * localPosition;
|
|
205
|
+
v_worldPosition = worldPosition.xyz;
|
|
206
|
+
v_normal = u_normalMatrix * localNormal;
|
|
207
|
+
v_tangent = vec4(u_normalMatrix * localTangent, a_tangent.w);
|
|
208
|
+
v_uv0 = applyUvTransform(a_uv0);
|
|
209
|
+
gl_Position = u_viewProjection * worldPosition;
|
|
210
|
+
}
|
|
211
|
+
`;
|
|
212
|
+
// The ShadedMaterial fragment: a classic diffuse + half-vector-specular base over the shared light
|
|
213
|
+
// block, with five modifier slot hooks. The base is a self-contained blinn-phong assembly (the third
|
|
214
|
+
// such assembly over GL_MESH_LIGHT_BLOCK_GLSL, alongside classic + PBR); the //@HOOK markers are
|
|
215
|
+
// substituted with injected modifier GLSL at compile time. The variables each hook may read/write
|
|
216
|
+
// are documented at the marker — this is the injection contract a GL modifier snippet targets.
|
|
217
|
+
const SHADED_FRAGMENT_TEMPLATE = `
|
|
218
|
+
precision highp float;
|
|
219
|
+
|
|
220
|
+
in vec3 v_worldPosition;
|
|
221
|
+
in vec3 v_normal;
|
|
222
|
+
in vec4 v_tangent;
|
|
223
|
+
in vec2 v_uv0;
|
|
224
|
+
|
|
225
|
+
uniform vec4 u_diffuse;
|
|
226
|
+
uniform vec4 u_specular;
|
|
227
|
+
uniform float u_shininess;
|
|
228
|
+
uniform float u_normalScale;
|
|
229
|
+
uniform float u_alphaCutoff;
|
|
230
|
+
uniform float u_time;
|
|
231
|
+
${GL_MESH_LIGHT_BLOCK_GLSL}
|
|
232
|
+
|
|
233
|
+
#ifdef HAS_DIFFUSE_MAP
|
|
234
|
+
uniform sampler2D u_diffuseMap;
|
|
235
|
+
#endif
|
|
236
|
+
#ifdef HAS_SPECULAR_MAP
|
|
237
|
+
uniform sampler2D u_specularMap;
|
|
238
|
+
#endif
|
|
239
|
+
#ifdef HAS_NORMAL_MAP
|
|
240
|
+
uniform sampler2D u_normalMap;
|
|
241
|
+
#endif
|
|
242
|
+
|
|
243
|
+
uniform float u_objectAlpha;
|
|
244
|
+
|
|
245
|
+
out vec4 fragColor;
|
|
246
|
+
|
|
247
|
+
// sRgb albedo texels are gamma-encoded; decode to linear before lighting.
|
|
248
|
+
vec3 srgbToLinear(vec3 c) {
|
|
249
|
+
vec3 lo = c / 12.92;
|
|
250
|
+
vec3 hi = pow((c + 0.055) / 1.055, vec3(2.4));
|
|
251
|
+
return mix(lo, hi, step(0.04045, c));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Deterministic 2D value noise, declared in the base so any Effect-slot modifier (the procedural
|
|
255
|
+
// dissolve mask) can call it without redeclaring a function — a GLSL compiler drops it when no
|
|
256
|
+
// modifier references it, so a plain ShadedMaterial pays nothing for it.
|
|
257
|
+
float shadedHashNoise(vec2 p) {
|
|
258
|
+
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
|
|
259
|
+
}
|
|
260
|
+
float shadedValueNoise(vec2 p) {
|
|
261
|
+
vec2 i = floor(p);
|
|
262
|
+
vec2 f = fract(p);
|
|
263
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
264
|
+
float a = shadedHashNoise(i + vec2(0.0, 0.0));
|
|
265
|
+
float b = shadedHashNoise(i + vec2(1.0, 0.0));
|
|
266
|
+
float c = shadedHashNoise(i + vec2(0.0, 1.0));
|
|
267
|
+
float d = shadedHashNoise(i + vec2(1.0, 1.0));
|
|
268
|
+
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Diffuse + half-vector (BlinnPhong) specular for ONE light. Every light type routes through this so
|
|
272
|
+
// they never fork the shading model — the caller supplies the surface->light direction and the
|
|
273
|
+
// (attenuated) radiance.
|
|
274
|
+
vec3 shadeShadedLight(vec3 normal, vec3 lightDir, vec3 lightColor, vec3 diffuseRgb, vec3 specularColor, float shininess) {
|
|
275
|
+
float nDotL = max(dot(normal, lightDir), 0.0);
|
|
276
|
+
vec3 result = diffuseRgb * nDotL * lightColor;
|
|
277
|
+
if (nDotL > 0.0) {
|
|
278
|
+
vec3 viewDir = normalize(u_cameraPosition - v_worldPosition);
|
|
279
|
+
vec3 halfVec = normalize(lightDir + viewDir);
|
|
280
|
+
float specAngle = max(dot(normal, halfVec), 0.0);
|
|
281
|
+
result += pow(specAngle, max(shininess, 1.0)) * specularColor * lightColor;
|
|
282
|
+
}
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
//@DECLARATIONS
|
|
287
|
+
|
|
288
|
+
void main() {
|
|
289
|
+
vec4 diffuse = u_diffuse;
|
|
290
|
+
#ifdef HAS_DIFFUSE_MAP
|
|
291
|
+
vec4 sampledDiffuse = texture(u_diffuseMap, v_uv0);
|
|
292
|
+
diffuse.rgb *= srgbToLinear(sampledDiffuse.rgb);
|
|
293
|
+
diffuse.a *= sampledDiffuse.a;
|
|
294
|
+
#endif
|
|
295
|
+
|
|
296
|
+
vec3 geometricNormal = normalize(v_normal);
|
|
297
|
+
if (!gl_FrontFacing) geometricNormal = -geometricNormal;
|
|
298
|
+
// Gram-Schmidt-reorthogonalize the interpolated tangent against the interpolated normal before
|
|
299
|
+
// building the TBN: linear interpolation across a triangle leaves v_tangent no longer perpendicular
|
|
300
|
+
// to v_normal, and skipping this step skews the tangent frame — the normal-map artifact this base
|
|
301
|
+
// shader previously exhibited. Mirrors the PBR prelude's TBN construction exactly.
|
|
302
|
+
vec3 tangent = normalize(v_tangent.xyz - geometricNormal * dot(v_tangent.xyz, geometricNormal));
|
|
303
|
+
vec3 bitangent = cross(geometricNormal, tangent) * v_tangent.w;
|
|
304
|
+
mat3 tbn = mat3(tangent, bitangent, geometricNormal);
|
|
305
|
+
|
|
306
|
+
vec3 normal = geometricNormal;
|
|
307
|
+
#ifdef HAS_NORMAL_MAP
|
|
308
|
+
vec3 baseTangentNormal = texture(u_normalMap, v_uv0).xyz * 2.0 - 1.0;
|
|
309
|
+
baseTangentNormal.xy *= u_normalScale;
|
|
310
|
+
normal = normalize(tbn * baseTangentNormal);
|
|
311
|
+
#endif
|
|
312
|
+
|
|
313
|
+
// Normal slot: read/write \`normal\` (the world-space shading normal). \`tbn\` maps tangent- to
|
|
314
|
+
// world-space; \`v_uv0\` and \`u_time\` drive scrolling perturbations.
|
|
315
|
+
//@NORMAL
|
|
316
|
+
|
|
317
|
+
vec3 specularColor = u_specular.rgb;
|
|
318
|
+
#ifdef HAS_SPECULAR_MAP
|
|
319
|
+
specularColor *= srgbToLinear(texture(u_specularMap, v_uv0).rgb);
|
|
320
|
+
#endif
|
|
321
|
+
float shininess = u_shininess;
|
|
322
|
+
|
|
323
|
+
// Diffuse slot: read/write \`diffuse\` (vec4 linear albedo + alpha).
|
|
324
|
+
//@DIFFUSE
|
|
325
|
+
// Specular slot: read/write \`specularColor\` (linear) and \`shininess\`.
|
|
326
|
+
//@SPECULAR
|
|
327
|
+
|
|
328
|
+
#ifdef ALPHA_MASK
|
|
329
|
+
if (diffuse.a < u_alphaCutoff) discard;
|
|
330
|
+
#endif
|
|
331
|
+
|
|
332
|
+
vec3 radiance = vec3(0.0);
|
|
333
|
+
|
|
334
|
+
// Directional light: -direction is the surface->light vector; modulated by the shared shadow term.
|
|
335
|
+
if (u_directionalCount > 0.5) {
|
|
336
|
+
vec3 lightDir = normalize(-u_directional.xyz);
|
|
337
|
+
float shadow = sampleDirectionalShadow(v_worldPosition);
|
|
338
|
+
radiance += shadeShadedLight(normal, lightDir, u_directionalRadiance.rgb, diffuse.rgb, specularColor, shininess) * shadow;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Point lights: surface->light direction with a smooth inverse-square range falloff.
|
|
342
|
+
for (int i = 0; i < MAX_FORWARD_LIGHTS; i++) {
|
|
343
|
+
if (i >= u_pointCount) break;
|
|
344
|
+
vec3 toLight = u_pointLights[i * 2 + 0].xyz - v_worldPosition;
|
|
345
|
+
float dist2 = dot(toLight, toLight);
|
|
346
|
+
vec3 lightDir = toLight * inversesqrt(max(dist2, 1e-8));
|
|
347
|
+
float atten = rangeWindow(dist2, u_pointLights[i * 2 + 1].w) / max(dist2, 1e-4);
|
|
348
|
+
radiance += shadeShadedLight(normal, lightDir, u_pointLights[i * 2 + 1].rgb * atten, diffuse.rgb, specularColor, shininess);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Spot lights: point attenuation times a smooth cone falloff between the inner/outer cosines.
|
|
352
|
+
for (int i = 0; i < MAX_FORWARD_LIGHTS; i++) {
|
|
353
|
+
if (i >= u_spotCount) break;
|
|
354
|
+
vec3 toLight = u_spotLights[i * 4 + 0].xyz - v_worldPosition;
|
|
355
|
+
float dist2 = dot(toLight, toLight);
|
|
356
|
+
vec3 lightDir = toLight * inversesqrt(max(dist2, 1e-8));
|
|
357
|
+
float atten = rangeWindow(dist2, u_spotLights[i * 4 + 1].w) / max(dist2, 1e-4);
|
|
358
|
+
float cone = smoothstep(u_spotLights[i * 4 + 3].y, u_spotLights[i * 4 + 3].x,
|
|
359
|
+
dot(normalize(u_spotLights[i * 4 + 2].xyz), -lightDir));
|
|
360
|
+
radiance += shadeShadedLight(normal, lightDir, u_spotLights[i * 4 + 1].rgb * atten * cone, diffuse.rgb, specularColor, shininess);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Ambient term: flat irradiance over the diffuse albedo.
|
|
364
|
+
if (u_ambientCount > 0.5) {
|
|
365
|
+
radiance += diffuse.rgb * u_ambientRadiance;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Hemisphere fill: sky/ground gradient blended by the normal's vertical component.
|
|
369
|
+
for (int i = 0; i < MAX_FORWARD_LIGHTS; i++) {
|
|
370
|
+
if (i >= u_hemisphereCount) break;
|
|
371
|
+
float f = 0.5 + 0.5 * dot(normal, u_hemisphereLights[i * 3 + 2].xyz);
|
|
372
|
+
radiance += mix(u_hemisphereLights[i * 3 + 1].rgb, u_hemisphereLights[i * 3 + 0].rgb, f) * diffuse.rgb;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Emissive slot: add self-illumination into \`emissive\` (linear radiance). \`normal\`, the light
|
|
376
|
+
// uniforms, and \`v_uv0\` are available for facing gates and masks.
|
|
377
|
+
vec3 emissive = vec3(0.0);
|
|
378
|
+
//@EMISSIVE
|
|
379
|
+
radiance += emissive;
|
|
380
|
+
|
|
381
|
+
// Effect slot: post-process the shaded \`radiance\` (view-dependent rim, tint, etc). \`viewDir\` is
|
|
382
|
+
// the world-space surface->camera direction; \`normal\` and \`v_uv0\` are available.
|
|
383
|
+
vec3 viewDir = normalize(u_cameraPosition - v_worldPosition);
|
|
384
|
+
//@EFFECT
|
|
385
|
+
|
|
386
|
+
fragColor = vec4(radiance, diffuse.a);
|
|
387
|
+
fragColor.a *= u_objectAlpha;
|
|
388
|
+
}
|
|
389
|
+
`;
|
|
390
|
+
// A shared frozen empty registry used as the no-snippets fallback when a state has never had a
|
|
391
|
+
// modifier snippet registered, so ensureGlShadedProgram allocates nothing per bind.
|
|
392
|
+
const EMPTY_MODIFIER_REGISTRY = createModifierRegistry();
|
|
393
|
+
//# sourceMappingURL=glShadedPrelude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glShadedPrelude.js","sourceRoot":"","sources":["../src/glShadedPrelude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glShadowMap.d.ts","sourceRoot":"","sources":["../src/glShadowMap.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAQ,MAAM,EAA+B,MAAM,iBAAiB,CAAC;AAmB1G,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,YAAY,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAC/B,IAAI,CA0FN"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { getCamera3DViewProjectionMatrix4 } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { hasMeshGeometrySkin } from '@flighthq/mesh';
|
|
4
|
+
import { forEachNodeDescendant, getNodeWorldMatrix4 } from '@flighthq/node';
|
|
5
|
+
import { createGlRenderTarget, uploadGlSkinPaletteTexture } from '@flighthq/render-gl';
|
|
6
|
+
import { compileGlProgram, ensureGlScene3DProgram, GL_SKIN_VERTEX_DECLARATIONS_GLSL, SKIN_PALETTE_TEXTURE_UNIT, } from './glMeshProgram';
|
|
7
|
+
import { ensureGlMeshUpload } from './glMeshUpload';
|
|
8
|
+
import { ensureGlSkinPalette, getGlScene3DRuntime } from './glScene3DRuntime';
|
|
9
|
+
// The directional shadow recipe's first pass: render scene depth from the light's point of view into a
|
|
10
|
+
// sampleable depth render target (the shadow map), and record it + the light view-projection on the
|
|
11
|
+
// scene runtime. The subsequent drawGlScene3D's lit binds (bindGlMeshLightBlock) read that to PCF-sample
|
|
12
|
+
// the shadow during shading. Shadows are opt-in: an app that never calls this leaves runtime.shadow
|
|
13
|
+
// null, so existing scenes render unchanged.
|
|
14
|
+
//
|
|
15
|
+
// `shadowCamera` is the orthographic light camera (see camera's configureDirectionalShadowCamera3D). All
|
|
16
|
+
// meshes are drawn (no frustum cull — an off-screen caster can still shadow the visible scene).
|
|
17
|
+
export function drawGlScene3DShadowMap(state, scene, shadowCamera) {
|
|
18
|
+
const gl = state.gl;
|
|
19
|
+
const runtime = getGlScene3DRuntime(state);
|
|
20
|
+
if (runtime.shadowTarget === null) {
|
|
21
|
+
runtime.shadowTarget = createGlRenderTarget(state, {
|
|
22
|
+
depth: 'depth-stencil-sampled',
|
|
23
|
+
height: SHADOW_MAP_SIZE,
|
|
24
|
+
width: SHADOW_MAP_SIZE,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const target = runtime.shadowTarget;
|
|
28
|
+
const matrix = runtime.shadow?.matrix ?? createMatrix4();
|
|
29
|
+
getCamera3DViewProjectionMatrix4(matrix, shadowCamera, 1);
|
|
30
|
+
const rigidProgram = ensureGlScene3DProgram(state, 'shadow:depth', compileShadowDepthProgram);
|
|
31
|
+
// Compiled lazily on the first GPU-skinned caster so a scene without skinned meshes never pays for it.
|
|
32
|
+
let skinnedProgram = null;
|
|
33
|
+
const prevFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
|
34
|
+
const prevViewport = gl.getParameter(gl.VIEWPORT);
|
|
35
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer);
|
|
36
|
+
gl.viewport(0, 0, target.width, target.height);
|
|
37
|
+
gl.enable(gl.DEPTH_TEST);
|
|
38
|
+
gl.depthFunc(gl.LESS);
|
|
39
|
+
gl.depthMask(true);
|
|
40
|
+
// Render back faces into the depth map (cull front). On a closed caster the recorded depth is the
|
|
41
|
+
// surface's far side, so the lit front faces compare against it and self-shadow acne disappears
|
|
42
|
+
// without a large depth bias. Open receivers (the ground plane) simply contribute nothing here,
|
|
43
|
+
// which is harmless — nothing lies beneath them to receive their cast.
|
|
44
|
+
gl.enable(gl.CULL_FACE);
|
|
45
|
+
gl.cullFace(gl.FRONT);
|
|
46
|
+
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
|
|
47
|
+
// u_viewProjection is per program (default uniforms persist per program object), so it is set on each
|
|
48
|
+
// program switch; u_model is per caster. boundProgram tracks the last program bound to avoid redundant
|
|
49
|
+
// useProgram + view-projection uploads across a run of same-kind casters.
|
|
50
|
+
let boundProgram = null;
|
|
51
|
+
forEachNodeDescendant(scene, (node) => {
|
|
52
|
+
// A drawable node carries geometry (structural, like prepareScene3DRender's mesh test).
|
|
53
|
+
const mesh = node;
|
|
54
|
+
if (mesh.geometry == null)
|
|
55
|
+
return;
|
|
56
|
+
// The caster is already at its CURRENT pose when this pass runs: the app drives prepareScene3DMorph +
|
|
57
|
+
// prepareScene3DSkinning before prepareScene3DRender, so morph is blended into geometry.vertices and the
|
|
58
|
+
// skin palette is current before either depth or forward draw. This pass just reads that pose, so an
|
|
59
|
+
// animated caster casts its animated silhouette without the depth pass re-deforming (and lagging or
|
|
60
|
+
// double-driving the forward pass). GPU skinning still deforms in the vertex shader from the bone
|
|
61
|
+
// palette, so a skinned caster needs the HAS_SKIN depth variant + the palette bound.
|
|
62
|
+
const skinned = mesh.skin != null && hasMeshGeometrySkin(mesh.geometry);
|
|
63
|
+
const program = skinned
|
|
64
|
+
? (skinnedProgram ??= ensureGlScene3DProgram(state, 'shadow:depth:skin', compileShadowDepthSkinnedProgram))
|
|
65
|
+
: rigidProgram;
|
|
66
|
+
if (program !== boundProgram) {
|
|
67
|
+
gl.useProgram(program.program);
|
|
68
|
+
gl.uniformMatrix4fv(program.locViewProjection, false, matrix.m);
|
|
69
|
+
boundProgram = program;
|
|
70
|
+
}
|
|
71
|
+
gl.uniformMatrix4fv(program.locModel, false, getNodeWorldMatrix4(mesh).m);
|
|
72
|
+
if (skinned) {
|
|
73
|
+
// Upload the mesh's bone palette into the shared RGBA32F skin texture and bind it, exactly as
|
|
74
|
+
// drawGlMeshSubset does for the forward pass, so the depth deformation matches the shaded one.
|
|
75
|
+
const jointMatrices = mesh.skin.skeleton.jointMatrices;
|
|
76
|
+
gl.activeTexture(gl.TEXTURE0 + SKIN_PALETTE_TEXTURE_UNIT);
|
|
77
|
+
uploadGlSkinPaletteTexture(gl, ensureGlSkinPalette(state), jointMatrices, (jointMatrices.length / 16) | 0);
|
|
78
|
+
gl.uniform1i(program.locJointTexture ?? null, SKIN_PALETTE_TEXTURE_UNIT);
|
|
79
|
+
}
|
|
80
|
+
// gpuSkinned = skinned: a skinned draw uploads the static bind pose (the shader deforms it via the
|
|
81
|
+
// palette) and wires the joints0/weights0 attributes; a rigid draw uploads geometry.vertices as-is.
|
|
82
|
+
const upload = ensureGlMeshUpload(state, mesh.geometry, skinned);
|
|
83
|
+
gl.bindVertexArray(upload.vao);
|
|
84
|
+
if (upload.indexBuffer !== null) {
|
|
85
|
+
gl.drawElements(upload.primitiveMode, upload.indexCount, upload.indexType, 0);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
gl.drawArrays(upload.primitiveMode, 0, upload.indexCount);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// Restore the active texture unit the forward pass assumes (0); a skinned caster left it on the palette unit.
|
|
92
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
93
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, prevFramebuffer);
|
|
94
|
+
gl.viewport(prevViewport[0], prevViewport[1], prevViewport[2], prevViewport[3]);
|
|
95
|
+
// Restore the default cull state the forward scene pass renders under (culling off, back-face mode).
|
|
96
|
+
gl.disable(gl.CULL_FACE);
|
|
97
|
+
gl.cullFace(gl.BACK);
|
|
98
|
+
runtime.shadow = { matrix, texture: target.depthTexture };
|
|
99
|
+
}
|
|
100
|
+
function compileShadowDepthProgram(gl) {
|
|
101
|
+
const program = compileGlProgram(gl, SHADOW_DEPTH_VERTEX, SHADOW_DEPTH_FRAGMENT);
|
|
102
|
+
return {
|
|
103
|
+
locModel: gl.getUniformLocation(program, 'u_model'),
|
|
104
|
+
locNormalMatrix: null,
|
|
105
|
+
locViewProjection: gl.getUniformLocation(program, 'u_viewProjection'),
|
|
106
|
+
program,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// The HAS_SKIN depth variant: the same depth pass, but the vertex is deformed by the bone palette via
|
|
110
|
+
// skinMatrix() before the model/view-projection transform — the exact deformation the forward HAS_SKIN
|
|
111
|
+
// vertex shader applies, so a skinned caster's recorded depth matches its shaded silhouette.
|
|
112
|
+
function compileShadowDepthSkinnedProgram(gl) {
|
|
113
|
+
const program = compileGlProgram(gl, SHADOW_DEPTH_SKINNED_VERTEX, SHADOW_DEPTH_FRAGMENT);
|
|
114
|
+
return {
|
|
115
|
+
locJointTexture: gl.getUniformLocation(program, 'u_jointTexture'),
|
|
116
|
+
locModel: gl.getUniformLocation(program, 'u_model'),
|
|
117
|
+
locNormalMatrix: null,
|
|
118
|
+
locViewProjection: gl.getUniformLocation(program, 'u_viewProjection'),
|
|
119
|
+
program,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const SHADOW_MAP_SIZE = 1024;
|
|
123
|
+
const SHADOW_DEPTH_VERTEX = `#version 300 es
|
|
124
|
+
layout(location = 0) in vec3 a_position;
|
|
125
|
+
uniform mat4 u_viewProjection;
|
|
126
|
+
uniform mat4 u_model;
|
|
127
|
+
void main() {
|
|
128
|
+
gl_Position = u_viewProjection * u_model * vec4(a_position, 1.0);
|
|
129
|
+
}
|
|
130
|
+
`;
|
|
131
|
+
// The skin declarations (joints0/weights0 attributes, the palette texture, and skinMatrix()) are spliced
|
|
132
|
+
// ahead of the body exactly as the family vertex shaders splice them; model * skinMatrix() matches the
|
|
133
|
+
// forward path's `worldPosition = u_model * (skin * position)`.
|
|
134
|
+
const SHADOW_DEPTH_SKINNED_VERTEX = `#version 300 es
|
|
135
|
+
${GL_SKIN_VERTEX_DECLARATIONS_GLSL}
|
|
136
|
+
layout(location = 0) in vec3 a_position;
|
|
137
|
+
uniform mat4 u_viewProjection;
|
|
138
|
+
uniform mat4 u_model;
|
|
139
|
+
void main() {
|
|
140
|
+
gl_Position = u_viewProjection * u_model * skinMatrix() * vec4(a_position, 1.0);
|
|
141
|
+
}
|
|
142
|
+
`;
|
|
143
|
+
const SHADOW_DEPTH_FRAGMENT = `#version 300 es
|
|
144
|
+
precision highp float;
|
|
145
|
+
out vec4 fragColor;
|
|
146
|
+
void main() {
|
|
147
|
+
fragColor = vec4(1.0);
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
//# sourceMappingURL=glShadowMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glShadowMap.js","sourceRoot":"","sources":["../src/glShadowMap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GlToonDefineKey, GlToonProgram, GlRenderState } from '@flighthq/types';
|
|
2
|
+
export declare function buildGlToonDefineKey(key: Readonly<GlToonDefineKey>): string;
|
|
3
|
+
export declare function compileGlToonProgram(gl: WebGL2RenderingContext, key: Readonly<GlToonDefineKey>): GlToonProgram;
|
|
4
|
+
export declare function ensureGlToonProgram(state: GlRenderState, key: Readonly<GlToonDefineKey>): GlToonProgram;
|
|
5
|
+
export declare function getGlToonFragmentSourceForKey(key: Readonly<GlToonDefineKey>): string;
|
|
6
|
+
export declare function getGlToonVertexSourceForKey(key: Readonly<GlToonDefineKey>): string;
|
|
7
|
+
//# sourceMappingURL=glToonPrelude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glToonPrelude.d.ts","sourceRoot":"","sources":["../src/glToonPrelude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAarF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,MAAM,CAI3E;AAOD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,sBAAsB,EAAE,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,aAAa,CAe9G;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,aAAa,CAUvG;AAGD,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,MAAM,CAEpF;AAGD,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,MAAM,CAGlF"}
|