@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,211 @@
|
|
|
1
|
+
import { MAX_FORWARD_LIGHTS, SCENE_LIGHT_HEMISPHERE_OFFSET, SCENE_LIGHT_HEMISPHERE_STRIDE, SCENE_LIGHT_POINT_OFFSET, SCENE_LIGHT_POINT_STRIDE, SCENE_LIGHT_SPOT_OFFSET, SCENE_LIGHT_SPOT_STRIDE, } from '@flighthq/types';
|
|
2
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
3
|
+
// The texture unit the directional shadow map binds to — above the material texture units (a material
|
|
4
|
+
// uses at most baseColor/normal/metallicRoughness/occlusion/emissive ⇒ units 0–4). The IBL set sits
|
|
5
|
+
// above the shadow map: irradiance/prefiltered cubemaps + the BRDF LUT on units 9/10/11.
|
|
6
|
+
const SHADOW_MAP_TEXTURE_UNIT = 8;
|
|
7
|
+
const IBL_IRRADIANCE_TEXTURE_UNIT = 9;
|
|
8
|
+
const IBL_PREFILTERED_TEXTURE_UNIT = 10;
|
|
9
|
+
const IBL_BRDF_TEXTURE_UNIT = 11;
|
|
10
|
+
const _iblPlaceholders = new WeakMap();
|
|
11
|
+
// The Scene3DLightBlock.version last uploaded into each program's light uniforms. Keyed by program
|
|
12
|
+
// because default uniforms are per-program state; freed with the program when it is GC'd.
|
|
13
|
+
const _uploadedLightVersion = new WeakMap();
|
|
14
|
+
const _uploadedLightBlock = new WeakMap();
|
|
15
|
+
// Uploads the packed light block to a lit program's standard light uniforms, then binds the active
|
|
16
|
+
// directional shadow (set by drawGlScene3DShadowMap on the scene runtime) or disables shadowing. The
|
|
17
|
+
// block layout (std140) mirrors Scene3DLightBlock.data exactly: directional { direction.xyz @0, _pad,
|
|
18
|
+
// radiance.rgb @4, _pad } then ambient { radiance.rgb @8, _pad }. Radiance is already linear and
|
|
19
|
+
// premultiplied at pack time. The count uniforms (0 or 1) gate each term. Every lit family calls this
|
|
20
|
+
// from bind() — it is the one place light + shadow data reach GL.
|
|
21
|
+
export function bindGlMeshLightBlock(state, program, lights) {
|
|
22
|
+
const gl = state.gl;
|
|
23
|
+
// The light uniforms are default (non-block) uniforms, which persist on the program object across
|
|
24
|
+
// useProgram switches and frames, so re-uploading an unchanged block is wasted work. packScene3DLightBlock
|
|
25
|
+
// only advances `version` on an actual change, so skip the upload when this program already holds the
|
|
26
|
+
// current version. Tracked per program (not per state) because each program keeps its own uniform
|
|
27
|
+
// values — a version cached on one program says nothing about another. Shadow and IBL binds below are
|
|
28
|
+
// NOT gated: they carry per-frame texture binds that must run every draw regardless of the light block.
|
|
29
|
+
if (_uploadedLightBlock.get(program) !== lights || _uploadedLightVersion.get(program) !== lights.version) {
|
|
30
|
+
const data = lights.data;
|
|
31
|
+
gl.uniform4f(program.locDirectional, data[0], data[1], data[2], 0);
|
|
32
|
+
gl.uniform4f(program.locDirectionalRadiance, data[4], data[5], data[6], 0);
|
|
33
|
+
gl.uniform3f(program.locAmbientRadiance, data[8], data[9], data[10]);
|
|
34
|
+
gl.uniform1f(program.locDirectionalCount, lights.directionalCount);
|
|
35
|
+
gl.uniform1f(program.locAmbientCount, lights.ambientCount);
|
|
36
|
+
// Punctual light arrays: upload the whole MAX_FORWARD_LIGHTS-wide slice as flat vec4 arrays (the
|
|
37
|
+
// shader loops each up to its count uniform). Subarray views over `data` — no copy — sliced at the
|
|
38
|
+
// same std140 offsets the CPU packer wrote. Classic/PBR programs both declare these; a program that
|
|
39
|
+
// resolves a location to null (none does today) simply no-ops the upload.
|
|
40
|
+
gl.uniform4fv(program.locPointLights, data.subarray(SCENE_LIGHT_POINT_OFFSET, SCENE_LIGHT_POINT_OFFSET + SCENE_LIGHT_POINT_STRIDE * MAX_FORWARD_LIGHTS));
|
|
41
|
+
gl.uniform4fv(program.locSpotLights, data.subarray(SCENE_LIGHT_SPOT_OFFSET, SCENE_LIGHT_SPOT_OFFSET + SCENE_LIGHT_SPOT_STRIDE * MAX_FORWARD_LIGHTS));
|
|
42
|
+
gl.uniform4fv(program.locHemisphereLights, data.subarray(SCENE_LIGHT_HEMISPHERE_OFFSET, SCENE_LIGHT_HEMISPHERE_OFFSET + SCENE_LIGHT_HEMISPHERE_STRIDE * MAX_FORWARD_LIGHTS));
|
|
43
|
+
gl.uniform1i(program.locPointCount, lights.pointCount);
|
|
44
|
+
gl.uniform1i(program.locSpotCount, lights.spotCount);
|
|
45
|
+
gl.uniform1i(program.locHemisphereCount, lights.hemisphereCount);
|
|
46
|
+
_uploadedLightBlock.set(program, lights);
|
|
47
|
+
_uploadedLightVersion.set(program, lights.version);
|
|
48
|
+
}
|
|
49
|
+
const runtime = getGlScene3DRuntime(state);
|
|
50
|
+
const shadow = runtime.shadow;
|
|
51
|
+
if (shadow !== null) {
|
|
52
|
+
gl.activeTexture(gl.TEXTURE0 + SHADOW_MAP_TEXTURE_UNIT);
|
|
53
|
+
gl.bindTexture(gl.TEXTURE_2D, shadow.texture);
|
|
54
|
+
gl.uniform1i(program.locShadowMap, SHADOW_MAP_TEXTURE_UNIT);
|
|
55
|
+
gl.uniformMatrix4fv(program.locShadowMatrix, false, shadow.matrix.m);
|
|
56
|
+
gl.uniform1f(program.locShadowEnabled, 1);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
gl.uniform1f(program.locShadowEnabled, 0);
|
|
60
|
+
}
|
|
61
|
+
// Image-based lighting (PBR families only; classic/toon programs resolve these locations to null so
|
|
62
|
+
// the binds are harmless no-ops). Bound here so every PBR draw samples the same baked environment.
|
|
63
|
+
const ibl = runtime.ibl;
|
|
64
|
+
if (ibl !== null) {
|
|
65
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_IRRADIANCE_TEXTURE_UNIT);
|
|
66
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, ibl.irradianceCube);
|
|
67
|
+
gl.uniform1i(program.locIblIrradiance, IBL_IRRADIANCE_TEXTURE_UNIT);
|
|
68
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_PREFILTERED_TEXTURE_UNIT);
|
|
69
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, ibl.prefilteredCube);
|
|
70
|
+
gl.uniform1i(program.locIblPrefiltered, IBL_PREFILTERED_TEXTURE_UNIT);
|
|
71
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_BRDF_TEXTURE_UNIT);
|
|
72
|
+
gl.bindTexture(gl.TEXTURE_2D, ibl.brdfLut);
|
|
73
|
+
gl.uniform1i(program.locIblBrdf, IBL_BRDF_TEXTURE_UNIT);
|
|
74
|
+
gl.uniform1f(program.locIblEnabled, 1);
|
|
75
|
+
gl.uniform1f(program.locIblIntensity, ibl.intensity);
|
|
76
|
+
gl.uniform1f(program.locIblMaxMip, ibl.prefilteredMipCount - 1);
|
|
77
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Even with IBL disabled, the PBR shader still *declares* the cube/2D IBL samplers, and a draw is
|
|
81
|
+
// invalid if a samplerCube and a sampler2D resolve to the same (default) texture unit 0. Bind
|
|
82
|
+
// correctly-typed 1x1 placeholders on the dedicated IBL units so the sampler types never collide
|
|
83
|
+
// with the material's unit-0 sampler — the dynamic u_iblEnabled gate keeps them unsampled.
|
|
84
|
+
const placeholders = ensureGlIblPlaceholders(state);
|
|
85
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_IRRADIANCE_TEXTURE_UNIT);
|
|
86
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, placeholders.cube);
|
|
87
|
+
gl.uniform1i(program.locIblIrradiance, IBL_IRRADIANCE_TEXTURE_UNIT);
|
|
88
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_PREFILTERED_TEXTURE_UNIT);
|
|
89
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, placeholders.cube);
|
|
90
|
+
gl.uniform1i(program.locIblPrefiltered, IBL_PREFILTERED_TEXTURE_UNIT);
|
|
91
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_BRDF_TEXTURE_UNIT);
|
|
92
|
+
gl.bindTexture(gl.TEXTURE_2D, placeholders.lut);
|
|
93
|
+
gl.uniform1i(program.locIblBrdf, IBL_BRDF_TEXTURE_UNIT);
|
|
94
|
+
gl.uniform1f(program.locIblEnabled, 0);
|
|
95
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Lazily creates (and caches per state) the 1x1 placeholder cube + 2D textures bound to the IBL units
|
|
99
|
+
// when no environment is baked. They exist only to give the PBR shader's IBL samplers a complete,
|
|
100
|
+
// correctly-typed binding so a draw is valid; they are never sampled (the u_iblEnabled gate is 0).
|
|
101
|
+
function ensureGlIblPlaceholders(state) {
|
|
102
|
+
let placeholders = _iblPlaceholders.get(state);
|
|
103
|
+
if (placeholders !== undefined)
|
|
104
|
+
return placeholders;
|
|
105
|
+
const gl = state.gl;
|
|
106
|
+
// Create on an IBL unit, never the active unit — the caller has the shadow map bound on unit 8, and
|
|
107
|
+
// binding here on the active unit would clobber it (the "black scene" bug). The else branch rebinds
|
|
108
|
+
// units 9/10/11 with proper activeTexture calls immediately after, so unit choice here only needs to
|
|
109
|
+
// avoid the shadow/material units.
|
|
110
|
+
gl.activeTexture(gl.TEXTURE0 + IBL_IRRADIANCE_TEXTURE_UNIT);
|
|
111
|
+
const black = new Uint8Array([0, 0, 0, 255]);
|
|
112
|
+
const cube = gl.createTexture();
|
|
113
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, cube);
|
|
114
|
+
for (let face = 0; face < 6; face++) {
|
|
115
|
+
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, black);
|
|
116
|
+
}
|
|
117
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
118
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
119
|
+
const lut = gl.createTexture();
|
|
120
|
+
gl.bindTexture(gl.TEXTURE_2D, lut);
|
|
121
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, black);
|
|
122
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
123
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
124
|
+
placeholders = { cube, lut };
|
|
125
|
+
_iblPlaceholders.set(state, placeholders);
|
|
126
|
+
return placeholders;
|
|
127
|
+
}
|
|
128
|
+
// Resolves the standard lit uniform locations from a linked program, so each lit family's compile
|
|
129
|
+
// spreads these in rather than repeating the getUniformLocation calls. The names match
|
|
130
|
+
// GL_MESH_LIGHT_BLOCK_GLSL — change them together.
|
|
131
|
+
export function resolveGlLitLocations(gl, program) {
|
|
132
|
+
return {
|
|
133
|
+
locAmbientCount: gl.getUniformLocation(program, 'u_ambientCount'),
|
|
134
|
+
locAmbientRadiance: gl.getUniformLocation(program, 'u_ambientRadiance'),
|
|
135
|
+
locCameraPosition: gl.getUniformLocation(program, 'u_cameraPosition'),
|
|
136
|
+
locDirectional: gl.getUniformLocation(program, 'u_directional'),
|
|
137
|
+
locDirectionalCount: gl.getUniformLocation(program, 'u_directionalCount'),
|
|
138
|
+
locDirectionalRadiance: gl.getUniformLocation(program, 'u_directionalRadiance'),
|
|
139
|
+
locHemisphereCount: gl.getUniformLocation(program, 'u_hemisphereCount'),
|
|
140
|
+
locHemisphereLights: gl.getUniformLocation(program, 'u_hemisphereLights'),
|
|
141
|
+
locIblBrdf: gl.getUniformLocation(program, 'u_iblBrdf'),
|
|
142
|
+
locIblEnabled: gl.getUniformLocation(program, 'u_iblEnabled'),
|
|
143
|
+
locIblIntensity: gl.getUniformLocation(program, 'u_iblIntensity'),
|
|
144
|
+
locIblIrradiance: gl.getUniformLocation(program, 'u_iblIrradiance'),
|
|
145
|
+
locIblMaxMip: gl.getUniformLocation(program, 'u_iblMaxMip'),
|
|
146
|
+
locIblPrefiltered: gl.getUniformLocation(program, 'u_iblPrefiltered'),
|
|
147
|
+
locPointCount: gl.getUniformLocation(program, 'u_pointCount'),
|
|
148
|
+
locPointLights: gl.getUniformLocation(program, 'u_pointLights'),
|
|
149
|
+
locShadowEnabled: gl.getUniformLocation(program, 'u_shadowEnabled'),
|
|
150
|
+
locShadowMap: gl.getUniformLocation(program, 'u_shadowMap'),
|
|
151
|
+
locShadowMatrix: gl.getUniformLocation(program, 'u_shadowMatrix'),
|
|
152
|
+
locSpotCount: gl.getUniformLocation(program, 'u_spotCount'),
|
|
153
|
+
locSpotLights: gl.getUniformLocation(program, 'u_spotLights'),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// The GLSL 300 es declaration of the standard forward-light + shadow uniforms and the shared
|
|
157
|
+
// shadow-sampling helper, included once in every lit fragment prelude. Keeping it here keeps the GPU
|
|
158
|
+
// declaration and the CPU upload (bindGlMeshLightBlock) in lockstep. A lit family that wants shadows
|
|
159
|
+
// multiplies its directional contribution by sampleDirectionalShadow(worldPos).
|
|
160
|
+
export const GL_MESH_LIGHT_BLOCK_GLSL = `
|
|
161
|
+
uniform vec4 u_directional; // xyz = light travel direction (surface->light is -xyz)
|
|
162
|
+
uniform vec4 u_directionalRadiance; // rgb = linear radiance, premultiplied by intensity
|
|
163
|
+
uniform vec3 u_ambientRadiance; // linear ambient irradiance
|
|
164
|
+
uniform float u_directionalCount; // 0 or 1 — gates the directional term
|
|
165
|
+
uniform float u_ambientCount; // 0 or 1 — gates the ambient term
|
|
166
|
+
uniform vec3 u_cameraPosition; // world-space camera position for view-dependent terms
|
|
167
|
+
uniform sampler2D u_shadowMap; // directional shadow depth map
|
|
168
|
+
uniform mat4 u_shadowMatrix; // world -> shadow light-clip
|
|
169
|
+
uniform float u_shadowEnabled; // 0 or 1 — gates shadow sampling
|
|
170
|
+
|
|
171
|
+
// Punctual (point/spot/hemisphere) forward-light arrays. Fixed MAX_FORWARD_LIGHTS-wide; each count
|
|
172
|
+
// uniform bounds its loop. Layout matches Scene3DLightBlock.data (packScene3DLightBlock) byte-for-byte:
|
|
173
|
+
// point[i] = u_pointLights[i*2+0]={pos.xyz,range}, [i*2+1]={radiance.rgb,invSqrRange}
|
|
174
|
+
// spot[i] = u_spotLights[i*4+0..1] as point, [i*4+2]={dir.xyz,_}, [i*4+3]={cosInner,cosOuter,_,_}
|
|
175
|
+
// hemisphere[i] = u_hemisphereLights[i*3+0]={sky.rgb,_}, [i*3+1]={ground.rgb,_}, [i*3+2]={up.xyz,_}
|
|
176
|
+
uniform vec4 u_pointLights[MAX_FORWARD_LIGHTS * 2];
|
|
177
|
+
uniform vec4 u_spotLights[MAX_FORWARD_LIGHTS * 4];
|
|
178
|
+
uniform vec4 u_hemisphereLights[MAX_FORWARD_LIGHTS * 3];
|
|
179
|
+
uniform int u_pointCount;
|
|
180
|
+
uniform int u_spotCount;
|
|
181
|
+
uniform int u_hemisphereCount;
|
|
182
|
+
|
|
183
|
+
// Smooth inverse-square range window (glTF/UE4): 1 near the light, eased to 0 at the range. invSqrRange
|
|
184
|
+
// is 1/range^2 (0 = infinite range, no cutoff). dist2 is the squared surface->light distance.
|
|
185
|
+
float rangeWindow(float dist2, float invSqrRange) {
|
|
186
|
+
float factor = dist2 * invSqrRange;
|
|
187
|
+
float windowed = clamp(1.0 - factor * factor, 0.0, 1.0);
|
|
188
|
+
return windowed * windowed;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Directional shadow factor at a world position: 1.0 fully lit, 0.0 fully shadowed, with 3x3 PCF.
|
|
192
|
+
// Fragments outside the shadow frustum are treated as lit.
|
|
193
|
+
float sampleDirectionalShadow(vec3 worldPos) {
|
|
194
|
+
if (u_shadowEnabled < 0.5) return 1.0;
|
|
195
|
+
vec4 clip = u_shadowMatrix * vec4(worldPos, 1.0);
|
|
196
|
+
vec3 ndc = clip.xyz / clip.w;
|
|
197
|
+
vec3 uvz = ndc * 0.5 + 0.5;
|
|
198
|
+
if (uvz.x < 0.0 || uvz.x > 1.0 || uvz.y < 0.0 || uvz.y > 1.0 || uvz.z > 1.0) return 1.0;
|
|
199
|
+
float current = uvz.z - 0.0025;
|
|
200
|
+
vec2 texel = 1.0 / vec2(textureSize(u_shadowMap, 0));
|
|
201
|
+
float sum = 0.0;
|
|
202
|
+
for (int x = -1; x <= 1; ++x) {
|
|
203
|
+
for (int y = -1; y <= 1; ++y) {
|
|
204
|
+
float closest = texture(u_shadowMap, uvz.xy + vec2(float(x), float(y)) * texel).r;
|
|
205
|
+
sum += current <= closest ? 1.0 : 0.0;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return sum / 9.0;
|
|
209
|
+
}
|
|
210
|
+
`;
|
|
211
|
+
//# sourceMappingURL=glLitProgram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glLitProgram.js","sourceRoot":"","sources":["../src/glLitProgram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GlMatcapDefineKey, GlMatcapProgram, LinearColor, GlRenderState, Texture } from '@flighthq/types';
|
|
2
|
+
export declare function bindGlMatcapSurface(state: GlRenderState, program: Readonly<GlMatcapProgram>, tint: Readonly<LinearColor>, matcap: Readonly<Texture> | null, alphaCutoff: number): void;
|
|
3
|
+
export declare function buildGlMatcapDefineKey(key: Readonly<GlMatcapDefineKey>): string;
|
|
4
|
+
export declare function compileGlMatcapProgram(gl: WebGL2RenderingContext, key: Readonly<GlMatcapDefineKey>): GlMatcapProgram;
|
|
5
|
+
export declare function ensureGlMatcapProgram(state: GlRenderState, key: Readonly<GlMatcapDefineKey>): GlMatcapProgram;
|
|
6
|
+
export declare function getGlMatcapFragmentSourceForKey(key: Readonly<GlMatcapDefineKey>): string;
|
|
7
|
+
export declare function getGlMatcapVertexSourceForKey(key: Readonly<GlMatcapDefineKey>): string;
|
|
8
|
+
//# sourceMappingURL=glMatcapPrelude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glMatcapPrelude.d.ts","sourceRoot":"","sources":["../src/glMatcapPrelude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAM/G,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC3B,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,EAChC,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAID,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAE/E;AAID,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,sBAAsB,EAAE,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,eAAe,CAYpH;AAID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,eAAe,CAI7G;AAGD,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAExF;AAGD,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAEtF"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { hasImageResourcePixels } from '@flighthq/image';
|
|
2
|
+
import { bindGlImageResourceTexture } from '@flighthq/render-gl';
|
|
3
|
+
import { compileGlProgram, ensureGlScene3DProgram } from './glMeshProgram';
|
|
4
|
+
// Uploads the resolved matcap surface uniforms: the linear tint (already sRgb-decoded on the CPU),
|
|
5
|
+
// the optional matcap texture on texture unit 0, and the alpha-mask cutoff. The caller has already
|
|
6
|
+
// selected the program (beginGlMeshDraw), set the view-projection, and uploaded u_view.
|
|
7
|
+
export function bindGlMatcapSurface(state, program, tint, matcap, alphaCutoff) {
|
|
8
|
+
const gl = state.gl;
|
|
9
|
+
gl.uniform4f(program.locTint, tint[0], tint[1], tint[2], tint[3]);
|
|
10
|
+
gl.uniform1f(program.locAlphaCutoff, alphaCutoff);
|
|
11
|
+
if (matcap !== null && matcap.image !== null && hasImageResourcePixels(matcap.image)) {
|
|
12
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
13
|
+
bindGlImageResourceTexture(state, matcap.image, matcap.sampler);
|
|
14
|
+
gl.uniform1i(program.locMatcap, 0);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// A short, stable, order-independent string identity for a matcap define key, used as the program-
|
|
18
|
+
// cache key. Two keys with the same flags produce the same string and so share a compiled program.
|
|
19
|
+
export function buildGlMatcapDefineKey(key) {
|
|
20
|
+
return `${key.alphaMaskEnabled ? 'm' : '-'}${key.hasMatcap ? 't' : '-'}`;
|
|
21
|
+
}
|
|
22
|
+
// Compiles the matcap shader for a define key, links it, and resolves its uniform locations. Pure GL
|
|
23
|
+
// work — no caching — used by ensureGlMatcapProgram.
|
|
24
|
+
export function compileGlMatcapProgram(gl, key) {
|
|
25
|
+
const program = compileGlProgram(gl, getGlMatcapVertexSourceForKey(key), getGlMatcapFragmentSourceForKey(key));
|
|
26
|
+
return {
|
|
27
|
+
locAlphaCutoff: gl.getUniformLocation(program, 'u_alphaCutoff'),
|
|
28
|
+
locMatcap: gl.getUniformLocation(program, 'u_matcap'),
|
|
29
|
+
locModel: gl.getUniformLocation(program, 'u_model'),
|
|
30
|
+
locNormalMatrix: gl.getUniformLocation(program, 'u_normalMatrix'),
|
|
31
|
+
locTint: gl.getUniformLocation(program, 'u_tint'),
|
|
32
|
+
locView: gl.getUniformLocation(program, 'u_view'),
|
|
33
|
+
locViewProjection: gl.getUniformLocation(program, 'u_viewProjection'),
|
|
34
|
+
program,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Resolves the matcap program for a define key, compiling and caching it on first use through the
|
|
38
|
+
// shared scene program cache under the `matcap:` family namespace.
|
|
39
|
+
export function ensureGlMatcapProgram(state, key) {
|
|
40
|
+
return ensureGlScene3DProgram(state, `matcap:${buildGlMatcapDefineKey(key)}`, (gl) => compileGlMatcapProgram(gl, key));
|
|
41
|
+
}
|
|
42
|
+
// The full fragment source for a define key (define block + body), ready to hand to the GL compiler.
|
|
43
|
+
export function getGlMatcapFragmentSourceForKey(key) {
|
|
44
|
+
return buildDefineSource(key) + MATCAP_FRAGMENT_BODY;
|
|
45
|
+
}
|
|
46
|
+
// The full vertex source for a define key (define block + body), ready to hand to the GL compiler.
|
|
47
|
+
export function getGlMatcapVertexSourceForKey(key) {
|
|
48
|
+
return buildDefineSource(key) + MATCAP_VERTEX_BODY;
|
|
49
|
+
}
|
|
50
|
+
function buildDefineSource(key) {
|
|
51
|
+
let defines = '#version 300 es\n';
|
|
52
|
+
if (key.alphaMaskEnabled)
|
|
53
|
+
defines += '#define ALPHA_MASK\n';
|
|
54
|
+
if (key.hasMatcap)
|
|
55
|
+
defines += '#define HAS_MATCAP\n';
|
|
56
|
+
return defines;
|
|
57
|
+
}
|
|
58
|
+
const MATCAP_VERTEX_BODY = `
|
|
59
|
+
layout(location = 0) in vec3 a_position;
|
|
60
|
+
layout(location = 1) in vec3 a_normal;
|
|
61
|
+
|
|
62
|
+
uniform mat4 u_viewProjection;
|
|
63
|
+
uniform mat4 u_model;
|
|
64
|
+
uniform mat4 u_view;
|
|
65
|
+
uniform mat3 u_normalMatrix;
|
|
66
|
+
|
|
67
|
+
out vec3 v_viewNormal;
|
|
68
|
+
|
|
69
|
+
void main() {
|
|
70
|
+
// u_normalMatrix takes the object normal into world space (handles model rotation/scale);
|
|
71
|
+
// mat3(u_view) rotates it into view space. Normalized in the fragment scene2d.
|
|
72
|
+
v_viewNormal = mat3(u_view) * (u_normalMatrix * a_normal);
|
|
73
|
+
gl_Position = u_viewProjection * u_model * vec4(a_position, 1.0);
|
|
74
|
+
}
|
|
75
|
+
`;
|
|
76
|
+
const MATCAP_FRAGMENT_BODY = `
|
|
77
|
+
precision highp float;
|
|
78
|
+
|
|
79
|
+
in vec3 v_viewNormal;
|
|
80
|
+
|
|
81
|
+
uniform vec4 u_tint;
|
|
82
|
+
#ifdef HAS_MATCAP
|
|
83
|
+
uniform sampler2D u_matcap;
|
|
84
|
+
#endif
|
|
85
|
+
#ifdef ALPHA_MASK
|
|
86
|
+
uniform float u_alphaCutoff;
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
uniform float u_objectAlpha;
|
|
90
|
+
|
|
91
|
+
out vec4 fragColor;
|
|
92
|
+
|
|
93
|
+
// sRgb texels are gamma-encoded; decode to linear before use. u_tint is already linear (decoded on
|
|
94
|
+
// the CPU at bind), so only the sampled matcap needs decoding.
|
|
95
|
+
vec3 srgbToLinear(vec3 c) {
|
|
96
|
+
vec3 lo = c / 12.92;
|
|
97
|
+
vec3 hi = pow((c + 0.055) / 1.055, vec3(2.4));
|
|
98
|
+
return mix(lo, hi, step(0.04045, c));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
void main() {
|
|
102
|
+
vec4 color = u_tint;
|
|
103
|
+
#ifdef HAS_MATCAP
|
|
104
|
+
// The view-space normal projected to 2D indexes the prebaked-lit sphere: uv = n.xy * 0.5 + 0.5.
|
|
105
|
+
vec3 viewNormal = normalize(v_viewNormal);
|
|
106
|
+
vec2 matcapUv = viewNormal.xy * 0.5 + 0.5;
|
|
107
|
+
vec4 sampled = texture(u_matcap, matcapUv);
|
|
108
|
+
color.rgb *= srgbToLinear(sampled.rgb);
|
|
109
|
+
color.a *= sampled.a;
|
|
110
|
+
#endif
|
|
111
|
+
#ifdef ALPHA_MASK
|
|
112
|
+
if (color.a < u_alphaCutoff) discard;
|
|
113
|
+
#endif
|
|
114
|
+
fragColor = color;
|
|
115
|
+
fragColor.a *= u_objectAlpha;
|
|
116
|
+
}
|
|
117
|
+
`;
|
|
118
|
+
//# sourceMappingURL=glMatcapPrelude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glMatcapPrelude.js","sourceRoot":"","sources":["../src/glMatcapPrelude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GlMeshMaterialRenderer, GlRenderState, Kind, Material } from '@flighthq/types';
|
|
2
|
+
export declare function getGlMeshMaterialRenderer(state: GlRenderState, kind: Kind): GlMeshMaterialRenderer | null;
|
|
3
|
+
export declare function registerGlMeshMaterialRenderer(state: GlRenderState, kind: Kind, renderer: GlMeshMaterialRenderer): void;
|
|
4
|
+
export declare function resolveGlMeshMaterialRenderer(state: GlRenderState, material: Readonly<Material> | null): GlMeshMaterialRenderer | null;
|
|
5
|
+
//# sourceMappingURL=glMeshMaterialRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glMeshMaterialRegistry.d.ts","sourceRoot":"","sources":["../src/glMeshMaterialRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAQ7F,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,sBAAsB,GAAG,IAAI,CAEzG;AAMD,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,sBAAsB,GAC/B,IAAI,CAEN;AAMD,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,GAClC,sBAAsB,GAAG,IAAI,CAO/B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DefaultMaterialKind } from '@flighthq/types';
|
|
2
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
3
|
+
// Returns the 3D mesh-material renderer registered for a kind on this state, or null. The 3D scene
|
|
4
|
+
// analog of getGlMaterialRenderer; reads scene-gl's own per-state registry (sceneMeshMaterialRegistry),
|
|
5
|
+
// distinct from the 2D materialRendererMap.
|
|
6
|
+
export function getGlMeshMaterialRenderer(state, kind) {
|
|
7
|
+
return getGlScene3DRuntime(state).materialRegistry.get(kind) ?? null;
|
|
8
|
+
}
|
|
9
|
+
// Registers a 3D mesh-material renderer against a material kind on this state. Opt-in: drawScene3D
|
|
10
|
+
// only draws subsets whose material kind (or DefaultMaterialKind) has a renderer here. Call
|
|
11
|
+
// registerStandardPbrGlMaterial for the built-in StandardPbr path. Mirrors registerGlMaterialRenderer
|
|
12
|
+
// but writes scene-gl's separate 3D registry.
|
|
13
|
+
export function registerGlMeshMaterialRenderer(state, kind, renderer) {
|
|
14
|
+
getGlScene3DRuntime(state).materialRegistry.set(kind, renderer);
|
|
15
|
+
}
|
|
16
|
+
// Resolves a mesh subset's material to its registered 3D renderer: by the material's kind, else the
|
|
17
|
+
// renderer registered for DefaultMaterialKind, else null. drawScene3D skips a subset whose material
|
|
18
|
+
// resolves to null (no built-in fallback — every material, including the default, enters only
|
|
19
|
+
// through registration). Mirrors resolveGlMaterialRenderer over the 3D registry.
|
|
20
|
+
export function resolveGlMeshMaterialRenderer(state, material) {
|
|
21
|
+
const registry = getGlScene3DRuntime(state).materialRegistry;
|
|
22
|
+
if (material !== null) {
|
|
23
|
+
const renderer = registry.get(material.kind);
|
|
24
|
+
if (renderer !== undefined)
|
|
25
|
+
return renderer;
|
|
26
|
+
}
|
|
27
|
+
return registry.get(DefaultMaterialKind) ?? null;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=glMeshMaterialRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glMeshMaterialRegistry.js","sourceRoot":"","sources":["../src/glMeshMaterialRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,mGAAmG;AACnG,wGAAwG;AACxG,4CAA4C;AAC5C,MAAM,UAAU,yBAAyB,CAAC,KAAoB,EAAE,IAAU;IACxE,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACvE,CAAC;AAED,mGAAmG;AACnG,4FAA4F;AAC5F,sGAAsG;AACtG,8CAA8C;AAC9C,MAAM,UAAU,8BAA8B,CAC5C,KAAoB,EACpB,IAAU,EACV,QAAgC;IAEhC,mBAAmB,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED,oGAAoG;AACpG,oGAAoG;AACpG,8FAA8F;AAC9F,iFAAiF;AACjF,MAAM,UAAU,6BAA6B,CAC3C,KAAoB,EACpB,QAAmC;IAEnC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC;IAC7D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;IAC9C,CAAC;IACD,OAAO,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GlMeshProgram, Camera3D, GlRenderState, MeshGeometry, Scene3DRenderProxy, TextureLike, VideoTexture } from '@flighthq/types';
|
|
2
|
+
export declare function beginGlMeshDraw(state: GlRenderState, program: Readonly<GlMeshProgram>, doubleSided: boolean): void;
|
|
3
|
+
export declare function bindGlUvTransform(gl: WebGL2RenderingContext, program: Readonly<GlMeshProgram>, texture: Readonly<TextureLike | VideoTexture> | null): void;
|
|
4
|
+
export declare function compileGlProgram(gl: WebGL2RenderingContext, vertexSource: string, fragmentSource: string): WebGLProgram;
|
|
5
|
+
export declare function destroyGlMeshProgram(state: GlRenderState, program: Readonly<GlMeshProgram>): void;
|
|
6
|
+
export declare function drawGlMeshSubset(state: GlRenderState, program: Readonly<GlMeshProgram>, proxy: Readonly<Scene3DRenderProxy>, geometry: Readonly<MeshGeometry>): void;
|
|
7
|
+
export declare function ensureGlScene3DProgram<T extends GlMeshProgram>(state: GlRenderState, key: string, compile: (gl: WebGL2RenderingContext) => T): T;
|
|
8
|
+
export declare function hasGlUvTransform(texture: Readonly<TextureLike | VideoTexture> | null): boolean;
|
|
9
|
+
export declare function setGlMeshCameraPosition(gl: WebGL2RenderingContext, locCameraPosition: WebGLUniformLocation | null, camera: Readonly<Camera3D>): void;
|
|
10
|
+
export declare function setGlMeshViewProjection(gl: WebGL2RenderingContext, locViewProjection: WebGLUniformLocation | null, camera: Readonly<Camera3D>): void;
|
|
11
|
+
export declare const GL_UV_TRANSFORM_VERTEX_GLSL = "\n#ifdef HAS_UV_TRANSFORM\nuniform mat3 u_uvTransform;\nvec2 applyUvTransform(vec2 uv) { return (u_uvTransform * vec3(uv, 1.0)).xy; }\n#else\nvec2 applyUvTransform(vec2 uv) { return uv; }\n#endif\n";
|
|
12
|
+
export declare const SKIN_PALETTE_TEXTURE_UNIT = 12;
|
|
13
|
+
export declare const GL_SKIN_VERTEX_DECLARATIONS_GLSL = "\nlayout(location = 6) in vec4 a_joints0;\nlayout(location = 7) in vec4 a_weights0;\nuniform highp sampler2D u_jointTexture;\n\nmat4 fetchJointMatrix(int joint) {\n int x = joint * 4;\n return mat4(\n texelFetch(u_jointTexture, ivec2(x, 0), 0),\n texelFetch(u_jointTexture, ivec2(x + 1, 0), 0),\n texelFetch(u_jointTexture, ivec2(x + 2, 0), 0),\n texelFetch(u_jointTexture, ivec2(x + 3, 0), 0)\n );\n}\n\nmat4 skinMatrix() {\n return a_weights0.x * fetchJointMatrix(int(a_joints0.x))\n + a_weights0.y * fetchJointMatrix(int(a_joints0.y))\n + a_weights0.z * fetchJointMatrix(int(a_joints0.z))\n + a_weights0.w * fetchJointMatrix(int(a_joints0.w));\n}\n";
|
|
14
|
+
//# sourceMappingURL=glMeshProgram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glMeshProgram.d.ts","sourceRoot":"","sources":["../src/glMeshProgram.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,aAAa,EACb,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,YAAY,EACb,MAAM,iBAAiB,CAAC;AAUzB,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI,CAelH;AAQD,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,sBAAsB,EAC1B,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,EAChC,OAAO,EAAE,QAAQ,CAAC,WAAW,GAAG,YAAY,CAAC,GAAG,IAAI,GACnD,IAAI,CASN;AAKD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,sBAAsB,EAC1B,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,YAAY,CAEd;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,IAAI,CAEjG;AAMD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,EAChC,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACnC,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC/B,IAAI,CAuCN;AAQD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,aAAa,EAC5D,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,EAAE,EAAE,sBAAsB,KAAK,CAAC,GACzC,CAAC,CAQH;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,GAAG,YAAY,CAAC,GAAG,IAAI,GAAG,OAAO,CAE9F;AAKD,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,sBAAsB,EAC1B,iBAAiB,EAAE,oBAAoB,GAAG,IAAI,EAC9C,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GACzB,IAAI,CAIN;AAKD,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,sBAAsB,EAC1B,iBAAiB,EAAE,oBAAoB,GAAG,IAAI,EAC9C,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GACzB,IAAI,CAIN;AAQD,eAAO,MAAM,2BAA2B,0MAOvC,CAAC;AAKF,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAU5C,eAAO,MAAM,gCAAgC,krBAqB5C,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { getCamera3DViewProjectionMatrix4 } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4, getMatrix4Position, inverseMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createGlProgram, uploadGlSkinPaletteTexture } from '@flighthq/render-gl';
|
|
4
|
+
import { getTextureUvMatrix, hasTextureUvTransform } from '@flighthq/texture';
|
|
5
|
+
import { ensureGlMeshUpload } from './glMeshUpload';
|
|
6
|
+
import { ensureGlSkinPalette, getGlScene3DRuntime } from './glScene3DRuntime';
|
|
7
|
+
// The shared per-bind head for every mesh-material family: stores the family's program as the active
|
|
8
|
+
// bind→draw handoff, selects it, and sets the depth + face-cull state a forward 3D draw needs (depth
|
|
9
|
+
// test LESS + depth write on; back-face cull unless the material is double-sided). The render-effect
|
|
10
|
+
// pipeline owns binding the rgba16f scene target and enabling depth at the framebuffer level; this
|
|
11
|
+
// fixes the per-material test/write/cull so a renderer invoked without the full pipeline still
|
|
12
|
+
// occludes correctly. A family's bind() calls this, then sets its own camera/material uniforms.
|
|
13
|
+
export function beginGlMeshDraw(state, program, doubleSided) {
|
|
14
|
+
const gl = state.gl;
|
|
15
|
+
getGlScene3DRuntime(state).activeMeshProgram = program;
|
|
16
|
+
gl.useProgram(program.program);
|
|
17
|
+
gl.enable(gl.DEPTH_TEST);
|
|
18
|
+
gl.depthFunc(gl.LESS);
|
|
19
|
+
gl.depthMask(true);
|
|
20
|
+
if (doubleSided) {
|
|
21
|
+
gl.disable(gl.CULL_FACE);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
gl.enable(gl.CULL_FACE);
|
|
25
|
+
gl.cullFace(gl.BACK);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Uploads a material's primary-texture uv transform to the HAS_UV_TRANSFORM vertex variant. Resolves
|
|
29
|
+
// u_uvTransform lazily and caches it on the program (mirroring locObjectAlpha): a null location means
|
|
30
|
+
// the compiled variant omits the uniform — the identity path — so this is a cheap no-op there, and a
|
|
31
|
+
// null texture likewise skips. @flighthq/texture composes the KHR_texture_transform column-major, so
|
|
32
|
+
// it uploads with transpose=false and `u_uvTransform * vec3(uv, 1.0)` matches the CPU
|
|
33
|
+
// transformTextureUv reference.
|
|
34
|
+
export function bindGlUvTransform(gl, program, texture) {
|
|
35
|
+
let loc = program.locUvTransform;
|
|
36
|
+
if (loc === undefined) {
|
|
37
|
+
loc = gl.getUniformLocation(program.program, 'u_uvTransform');
|
|
38
|
+
program.locUvTransform = loc;
|
|
39
|
+
}
|
|
40
|
+
if (loc === null || texture === null)
|
|
41
|
+
return;
|
|
42
|
+
getTextureUvMatrix(scratchUvMatrix, texture);
|
|
43
|
+
gl.uniformMatrix3fv(loc, false, scratchUvMatrix.m);
|
|
44
|
+
}
|
|
45
|
+
// Compiles a vertex + fragment source pair into a linked GL program. Shared by every family's
|
|
46
|
+
// program compile. Throws on a compile or link failure, which is a programmer error (a malformed
|
|
47
|
+
// prelude), not an expected runtime condition — correct preludes always compile.
|
|
48
|
+
export function compileGlProgram(gl, vertexSource, fragmentSource) {
|
|
49
|
+
return createGlProgram(gl, vertexSource, fragmentSource, 'Mesh');
|
|
50
|
+
}
|
|
51
|
+
// Frees the linked GL program backing a mesh-material family program. The program object must not be
|
|
52
|
+
// used after this call. Deleting an already-deleted GL program is a silent no-op, so destroying a
|
|
53
|
+
// program that a sibling render state still aliases is safe. Frees only the shader — the caller drops
|
|
54
|
+
// the program from its cache separately (see destroyGlScene3DRuntime, which does both).
|
|
55
|
+
export function destroyGlMeshProgram(state, program) {
|
|
56
|
+
state.gl.deleteProgram(program.program);
|
|
57
|
+
}
|
|
58
|
+
// The shared per-draw tail for every mesh-material family: uploads the model + normal matrices from
|
|
59
|
+
// the proxy, lazily uploads the geometry's GPU buffers (cached by geometry.version), and issues the
|
|
60
|
+
// indexed (or array) draw over the proxy's subset range. Families call this from draw() after bind()
|
|
61
|
+
// has selected and stored their program, so the geometry path lives in exactly one place.
|
|
62
|
+
export function drawGlMeshSubset(state, program, proxy, geometry) {
|
|
63
|
+
const gl = state.gl;
|
|
64
|
+
gl.uniformMatrix4fv(program.locModel, false, proxy.worldMatrix.m);
|
|
65
|
+
if (program.locNormalMatrix !== null)
|
|
66
|
+
gl.uniformMatrix3fv(program.locNormalMatrix, false, proxy.normalMatrix.m);
|
|
67
|
+
// Resolve u_objectAlpha once per program (undefined until first draw), then upload the resolved
|
|
68
|
+
// per-object opacity when the shader declares it. A program whose fragment scene2d lacks the uniform
|
|
69
|
+
// caches a null location and skips silently, so families without it cost nothing beyond one lookup.
|
|
70
|
+
let locObjectAlpha = program.locObjectAlpha;
|
|
71
|
+
if (locObjectAlpha === undefined) {
|
|
72
|
+
locObjectAlpha = gl.getUniformLocation(program.program, 'u_objectAlpha');
|
|
73
|
+
program.locObjectAlpha = locObjectAlpha;
|
|
74
|
+
}
|
|
75
|
+
if (locObjectAlpha !== null)
|
|
76
|
+
gl.uniform1f(locObjectAlpha, proxy.alpha ?? 1);
|
|
77
|
+
// GPU skinning: upload the mesh's bone palette into the per-state RGBA32F data texture and bind it on
|
|
78
|
+
// the skin-palette texture unit for the HAS_SKIN variant. Only a skinned program has the location, and
|
|
79
|
+
// only a skinned mesh carries a palette; a mismatch (one without the other) simply skips the upload and
|
|
80
|
+
// the shader falls back to its rigid path. The joint count is the palette length / 16 (16 floats/mat4).
|
|
81
|
+
const jointMatrices = proxy.jointMatrices;
|
|
82
|
+
const gpuSkinned = program.locJointTexture != null && jointMatrices != null;
|
|
83
|
+
if (gpuSkinned) {
|
|
84
|
+
const palette = ensureGlSkinPalette(state);
|
|
85
|
+
gl.activeTexture(gl.TEXTURE0 + SKIN_PALETTE_TEXTURE_UNIT);
|
|
86
|
+
uploadGlSkinPaletteTexture(gl, palette, jointMatrices, (jointMatrices.length / 16) | 0);
|
|
87
|
+
gl.uniform1i(program.locJointTexture, SKIN_PALETTE_TEXTURE_UNIT);
|
|
88
|
+
}
|
|
89
|
+
// A GPU-skinned draw uploads the static bind pose (the shader deforms it via the palette), so the
|
|
90
|
+
// per-frame CPU pose updateMeshSkin also writes to geometry.vertices is not re-applied on top.
|
|
91
|
+
const upload = ensureGlMeshUpload(state, geometry, gpuSkinned);
|
|
92
|
+
const subset = proxy.subset;
|
|
93
|
+
if (upload.indexBuffer !== null) {
|
|
94
|
+
const elementSize = upload.indexType === gl.UNSIGNED_INT ? 4 : 2;
|
|
95
|
+
gl.drawElements(upload.primitiveMode, subset.indexCount, upload.indexType, subset.indexOffset * elementSize);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
gl.drawArrays(upload.primitiveMode, subset.indexOffset, subset.indexCount);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Resolves a compiled program for a string cache key, compiling it via the factory on first use and
|
|
102
|
+
// caching it on the scene runtime's per-state programCache. Every family routes its program through
|
|
103
|
+
// this one cache; the key is namespaced by family + define key (for example `unlit:b-`), so distinct
|
|
104
|
+
// families and feature variants compile at most once per state and never collide. The factory returns
|
|
105
|
+
// the family's program record (locations resolved at compile time); the cast is sound because the key
|
|
106
|
+
// namespace guarantees a given key always maps to the same family's program shape.
|
|
107
|
+
export function ensureGlScene3DProgram(state, key, compile) {
|
|
108
|
+
const runtime = getGlScene3DRuntime(state);
|
|
109
|
+
let program = runtime.programCache.get(key);
|
|
110
|
+
if (program === undefined) {
|
|
111
|
+
program = compile(state.gl);
|
|
112
|
+
runtime.programCache.set(key, program);
|
|
113
|
+
}
|
|
114
|
+
return program;
|
|
115
|
+
}
|
|
116
|
+
// The HAS_UV_TRANSFORM define-key predicate every map-sampling family shares: true only when the
|
|
117
|
+
// material's primary map is bound (an image is present, so it is actually sampled) AND carries a
|
|
118
|
+
// non-identity uv transform. Gating on both keeps an untiled or unbound surface on the identity shader
|
|
119
|
+
// variant, so it never pays for the uv-transform uniform or the extra vertex multiply.
|
|
120
|
+
export function hasGlUvTransform(texture) {
|
|
121
|
+
return texture !== null && (!('image' in texture) || texture.image !== null) && hasTextureUvTransform(texture);
|
|
122
|
+
}
|
|
123
|
+
// Uploads the camera world position (the translation of the inverse view matrix) to a lit family's
|
|
124
|
+
// u_cameraPosition. Lighting-independent families (unlit/debug) skip this — only families whose
|
|
125
|
+
// fragment scene2d needs a view vector resolve and bind a camera-position location.
|
|
126
|
+
export function setGlMeshCameraPosition(gl, locCameraPosition, camera) {
|
|
127
|
+
inverseMatrix4(scratchInverseView, camera.view);
|
|
128
|
+
getMatrix4Position(scratchCameraPosition, scratchInverseView);
|
|
129
|
+
gl.uniform3f(locCameraPosition, scratchCameraPosition.x, scratchCameraPosition.y, scratchCameraPosition.z);
|
|
130
|
+
}
|
|
131
|
+
// Uploads the camera view-projection matrix to a program's u_viewProjection. Every family's vertex
|
|
132
|
+
// scene2d shares this transform; the perspective aspect falls back to 1 when zero (degenerate camera)
|
|
133
|
+
// so a malformed projection never divides by zero.
|
|
134
|
+
export function setGlMeshViewProjection(gl, locViewProjection, camera) {
|
|
135
|
+
const aspect = camera.projection.kind === 'perspective' ? camera.projection.aspect : 1;
|
|
136
|
+
getCamera3DViewProjectionMatrix4(scratchViewProjection, camera, aspect !== 0 ? aspect : 1);
|
|
137
|
+
gl.uniformMatrix4fv(locViewProjection, false, scratchViewProjection.m);
|
|
138
|
+
}
|
|
139
|
+
// Vertex-scene2d GLSL every map-sampling family interpolates into its vertex body ahead of `main`: the
|
|
140
|
+
// guarded u_uvTransform uniform and an applyUvTransform() the body calls on a_uv0 instead of passing
|
|
141
|
+
// it through. HAS_UV_TRANSFORM — set by a family's define block only when its primary texture carries a
|
|
142
|
+
// non-identity transform (see hasTextureUvTransform) — gates both the uniform and the mat3 multiply, so
|
|
143
|
+
// an untiled surface compiles the identity branch (inlined away) and pays nothing: the assembly never
|
|
144
|
+
// taxes the primitive. u_uvTransform is column-major (see bindGlUvTransform).
|
|
145
|
+
export const GL_UV_TRANSFORM_VERTEX_GLSL = `
|
|
146
|
+
#ifdef HAS_UV_TRANSFORM
|
|
147
|
+
uniform mat3 u_uvTransform;
|
|
148
|
+
vec2 applyUvTransform(vec2 uv) { return (u_uvTransform * vec3(uv, 1.0)).xy; }
|
|
149
|
+
#else
|
|
150
|
+
vec2 applyUvTransform(vec2 uv) { return uv; }
|
|
151
|
+
#endif
|
|
152
|
+
`;
|
|
153
|
+
// The GPU skin-palette bone texture is read from this texture unit — above the material maps (0–4), the
|
|
154
|
+
// directional shadow map (8), and the IBL set (9/10/11), so a skinned lit draw never collides with any of
|
|
155
|
+
// them. drawGlMeshSubset binds the palette texture here and sets u_jointTexture to this unit.
|
|
156
|
+
export const SKIN_PALETTE_TEXTURE_UNIT = 12;
|
|
157
|
+
// Vertex-scene2d GLSL the HAS_SKIN variant prepends before the family's vertex body: the joints0/weights0
|
|
158
|
+
// influence attributes (locations 6/7, wired by ensureGlMeshUpload), the bone-palette DATA TEXTURE, and
|
|
159
|
+
// the linear-blend `skinMatrix()` the body applies to position/normal/tangent. The palette is an RGBA32F
|
|
160
|
+
// texture read with texelFetch (GLSL ES 3.0 core — no float-filter extension), one mat4 packed as four
|
|
161
|
+
// consecutive texels (column 0..3) so joint j's column c is at texel (j*4 + c, 0). Replaces the old
|
|
162
|
+
// `uniform mat4 u_jointMatrices[MAX_JOINTS]` array: the joint count is bounded by MAX_TEXTURE_SIZE, so
|
|
163
|
+
// there is no `#define MAX_JOINTS` cap and no CPU fallback above a uniform-budget capacity. Vertex-only —
|
|
164
|
+
// never added to a fragment source (the `in` attributes are illegal there).
|
|
165
|
+
export const GL_SKIN_VERTEX_DECLARATIONS_GLSL = `
|
|
166
|
+
layout(location = 6) in vec4 a_joints0;
|
|
167
|
+
layout(location = 7) in vec4 a_weights0;
|
|
168
|
+
uniform highp sampler2D u_jointTexture;
|
|
169
|
+
|
|
170
|
+
mat4 fetchJointMatrix(int joint) {
|
|
171
|
+
int x = joint * 4;
|
|
172
|
+
return mat4(
|
|
173
|
+
texelFetch(u_jointTexture, ivec2(x, 0), 0),
|
|
174
|
+
texelFetch(u_jointTexture, ivec2(x + 1, 0), 0),
|
|
175
|
+
texelFetch(u_jointTexture, ivec2(x + 2, 0), 0),
|
|
176
|
+
texelFetch(u_jointTexture, ivec2(x + 3, 0), 0)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
mat4 skinMatrix() {
|
|
181
|
+
return a_weights0.x * fetchJointMatrix(int(a_joints0.x))
|
|
182
|
+
+ a_weights0.y * fetchJointMatrix(int(a_joints0.y))
|
|
183
|
+
+ a_weights0.z * fetchJointMatrix(int(a_joints0.z))
|
|
184
|
+
+ a_weights0.w * fetchJointMatrix(int(a_joints0.w));
|
|
185
|
+
}
|
|
186
|
+
`;
|
|
187
|
+
const scratchViewProjection = createMatrix4();
|
|
188
|
+
const scratchInverseView = createMatrix4();
|
|
189
|
+
const scratchCameraPosition = { x: 0, y: 0, z: 0 };
|
|
190
|
+
// Column-major uv matrix composed per bind and uploaded directly; reused across every
|
|
191
|
+
// bindGlUvTransform call (single-threaded GL draw path).
|
|
192
|
+
const scratchUvMatrix = createMatrix3();
|
|
193
|
+
//# sourceMappingURL=glMeshProgram.js.map
|