@aura3d/engine 1.4.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -30
- package/dist/animation/Retargeting.d.ts +12 -0
- package/dist/animation/Retargeting.d.ts.map +1 -0
- package/dist/animation/Retargeting.js +19 -0
- package/dist/animation/Retargeting.js.map +1 -0
- package/dist/assets/GLTFLoader.d.ts +4 -0
- package/dist/assets/GLTFLoader.d.ts.map +1 -1
- package/dist/assets/GLTFLoader.js +39 -4
- package/dist/assets/GLTFLoader.js.map +1 -1
- package/dist/assets/GLTFRenderResources.d.ts +16 -0
- package/dist/assets/GLTFRenderResources.d.ts.map +1 -1
- package/dist/assets/GLTFRenderResources.js +42 -2
- package/dist/assets/GLTFRenderResources.js.map +1 -1
- package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts +6 -0
- package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts.map +1 -1
- package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js +2 -1
- package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js.map +1 -1
- package/dist/assets/index.d.ts +0 -1
- package/dist/assets/index.d.ts.map +1 -1
- package/dist/assets/index.js +0 -1
- package/dist/assets/index.js.map +1 -1
- package/dist/assets/loaders/index.d.ts +0 -1
- package/dist/assets/loaders/index.d.ts.map +1 -1
- package/dist/assets/loaders/index.js +0 -1
- package/dist/assets/loaders/index.js.map +1 -1
- package/dist/aura3d-cli/asset-intent.d.ts +148 -0
- package/dist/aura3d-cli/asset-intent.d.ts.map +1 -0
- package/dist/aura3d-cli/asset-intent.js +145 -0
- package/dist/aura3d-cli/asset-intent.js.map +1 -0
- package/dist/aura3d-cli/asset-role-admission.d.ts +174 -0
- package/dist/aura3d-cli/asset-role-admission.d.ts.map +1 -0
- package/dist/aura3d-cli/asset-role-admission.js +381 -0
- package/dist/aura3d-cli/asset-role-admission.js.map +1 -0
- package/dist/aura3d-cli/asset-screening-effects.d.ts +95 -0
- package/dist/aura3d-cli/asset-screening-effects.d.ts.map +1 -0
- package/dist/aura3d-cli/asset-screening-effects.js +321 -0
- package/dist/aura3d-cli/asset-screening-effects.js.map +1 -0
- package/dist/aura3d-cli/asset-screening-pipeline.d.ts +132 -0
- package/dist/aura3d-cli/asset-screening-pipeline.d.ts.map +1 -0
- package/dist/aura3d-cli/asset-screening-pipeline.js +277 -0
- package/dist/aura3d-cli/asset-screening-pipeline.js.map +1 -0
- package/dist/aura3d-cli/cartoon-asset-profiles.d.ts +15 -0
- package/dist/aura3d-cli/cartoon-asset-profiles.d.ts.map +1 -0
- package/dist/aura3d-cli/cartoon-asset-profiles.js +46 -0
- package/dist/aura3d-cli/cartoon-asset-profiles.js.map +1 -0
- package/dist/aura3d-cli/cli-help.js +1 -1
- package/dist/aura3d-cli/cli.js +16 -2
- package/dist/aura3d-cli/cli.js.map +1 -1
- package/dist/aura3d-cli/index.d.ts +8 -0
- package/dist/aura3d-cli/index.d.ts.map +1 -1
- package/dist/aura3d-cli/index.js +390 -17
- package/dist/aura3d-cli/index.js.map +1 -1
- package/dist/aura3d-cli/pull-bridge/search.d.ts +4 -0
- package/dist/aura3d-cli/pull-bridge/search.d.ts.map +1 -1
- package/dist/aura3d-cli/pull-bridge/search.js +22 -0
- package/dist/aura3d-cli/pull-bridge/search.js.map +1 -1
- package/dist/aura3d-cli/pull-bridge.d.ts +20 -5
- package/dist/aura3d-cli/pull-bridge.d.ts.map +1 -1
- package/dist/aura3d-cli/pull-bridge.js +38 -1
- package/dist/aura3d-cli/pull-bridge.js.map +1 -1
- package/dist/controls/ControlState.d.ts +1 -1
- package/dist/controls/ControlState.d.ts.map +1 -1
- package/dist/controls/DragControls.d.ts +21 -1
- package/dist/controls/DragControls.d.ts.map +1 -1
- package/dist/controls/DragControls.js +24 -2
- package/dist/controls/DragControls.js.map +1 -1
- package/dist/controls/FirstPersonControls.d.ts +10 -1
- package/dist/controls/FirstPersonControls.d.ts.map +1 -1
- package/dist/controls/FirstPersonControls.js +18 -2
- package/dist/controls/FirstPersonControls.js.map +1 -1
- package/dist/controls/FlyControls.d.ts +42 -0
- package/dist/controls/FlyControls.d.ts.map +1 -1
- package/dist/controls/FlyControls.js +106 -3
- package/dist/controls/FlyControls.js.map +1 -1
- package/dist/controls/MapControls.d.ts +13 -0
- package/dist/controls/MapControls.d.ts.map +1 -1
- package/dist/controls/MapControls.js +40 -2
- package/dist/controls/MapControls.js.map +1 -1
- package/dist/controls/OrbitControls.d.ts +54 -0
- package/dist/controls/OrbitControls.d.ts.map +1 -1
- package/dist/controls/OrbitControls.js +133 -0
- package/dist/controls/OrbitControls.js.map +1 -1
- package/dist/controls/PointerLockControls.d.ts +12 -5
- package/dist/controls/PointerLockControls.d.ts.map +1 -1
- package/dist/controls/PointerLockControls.js +30 -11
- package/dist/controls/PointerLockControls.js.map +1 -1
- package/dist/controls/SelectionManager.d.ts +22 -1
- package/dist/controls/SelectionManager.d.ts.map +1 -1
- package/dist/controls/SelectionManager.js +64 -6
- package/dist/controls/SelectionManager.js.map +1 -1
- package/dist/controls/TransformControls.d.ts +135 -1
- package/dist/controls/TransformControls.d.ts.map +1 -1
- package/dist/controls/TransformControls.js +534 -10
- package/dist/controls/TransformControls.js.map +1 -1
- package/dist/controls/index.d.ts +7 -2
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +1 -1
- package/dist/controls/index.js.map +1 -1
- package/dist/create-aura3d/index.js +1 -1
- package/dist/create-aura3d/showcase-spec-game-geometry-extractor.d.ts +2 -0
- package/dist/create-aura3d/showcase-spec-game-geometry-extractor.d.ts.map +1 -1
- package/dist/create-aura3d/showcase-spec-game-geometry-extractor.js +781 -46
- package/dist/create-aura3d/showcase-spec-game-geometry-extractor.js.map +1 -1
- package/dist/create-aura3d/showcase-spec-game-template-evidence.d.ts.map +1 -1
- package/dist/create-aura3d/showcase-spec-game-template-evidence.js +24 -4
- package/dist/create-aura3d/showcase-spec-game-template-evidence.js.map +1 -1
- package/dist/create-aura3d/showcase-spec-platformer-artifacts.d.ts.map +1 -1
- package/dist/create-aura3d/showcase-spec-platformer-artifacts.js +28 -17
- package/dist/create-aura3d/showcase-spec-platformer-artifacts.js.map +1 -1
- package/dist/create-aura3d/showcase-spec-racing-artifacts.d.ts.map +1 -1
- package/dist/create-aura3d/showcase-spec-racing-artifacts.js +10 -5
- package/dist/create-aura3d/showcase-spec-racing-artifacts.js.map +1 -1
- package/dist/create-aura3d/showcase-spec-replacement-candidates.js +26 -0
- package/dist/create-aura3d/showcase-spec-replacement-candidates.js.map +1 -1
- package/dist/ecs/components/MeshComponent.d.ts +5 -2
- package/dist/ecs/components/MeshComponent.d.ts.map +1 -1
- package/dist/ecs/components/MeshComponent.js.map +1 -1
- package/dist/editor-runtime/CartoonSceneEditor.d.ts +111 -0
- package/dist/editor-runtime/CartoonSceneEditor.d.ts.map +1 -0
- package/dist/editor-runtime/CartoonSceneEditor.js +285 -0
- package/dist/editor-runtime/CartoonSceneEditor.js.map +1 -0
- package/dist/editor-runtime/InteractiveTransformGizmo.d.ts +142 -0
- package/dist/editor-runtime/InteractiveTransformGizmo.d.ts.map +1 -0
- package/dist/editor-runtime/InteractiveTransformGizmo.js +468 -0
- package/dist/editor-runtime/InteractiveTransformGizmo.js.map +1 -0
- package/dist/editor-runtime/index.d.ts +2 -0
- package/dist/editor-runtime/index.d.ts.map +1 -1
- package/dist/editor-runtime/index.js +1 -0
- package/dist/editor-runtime/index.js.map +1 -1
- package/dist/engine/agent-api/CartoonAssetManifest.d.ts +50 -0
- package/dist/engine/agent-api/CartoonAssetManifest.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonAssetManifest.js +65 -0
- package/dist/engine/agent-api/CartoonAssetManifest.js.map +1 -0
- package/dist/engine/agent-api/CartoonDirector.d.ts +120 -0
- package/dist/engine/agent-api/CartoonDirector.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonDirector.js +432 -0
- package/dist/engine/agent-api/CartoonDirector.js.map +1 -0
- package/dist/engine/agent-api/CartoonEpisodePackage.d.ts +51 -0
- package/dist/engine/agent-api/CartoonEpisodePackage.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonEpisodePackage.js +79 -0
- package/dist/engine/agent-api/CartoonEpisodePackage.js.map +1 -0
- package/dist/engine/agent-api/CartoonMotionQuality.d.ts +83 -0
- package/dist/engine/agent-api/CartoonMotionQuality.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonMotionQuality.js +128 -0
- package/dist/engine/agent-api/CartoonMotionQuality.js.map +1 -0
- package/dist/engine/agent-api/CartoonPerformance.d.ts +150 -0
- package/dist/engine/agent-api/CartoonPerformance.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonPerformance.js +345 -0
- package/dist/engine/agent-api/CartoonPerformance.js.map +1 -0
- package/dist/engine/agent-api/CartoonRenderQueue.d.ts +143 -0
- package/dist/engine/agent-api/CartoonRenderQueue.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonRenderQueue.js +410 -0
- package/dist/engine/agent-api/CartoonRenderQueue.js.map +1 -0
- package/dist/engine/agent-api/CartoonRouteProof.d.ts +112 -0
- package/dist/engine/agent-api/CartoonRouteProof.d.ts.map +1 -0
- package/dist/engine/agent-api/CartoonRouteProof.js +127 -0
- package/dist/engine/agent-api/CartoonRouteProof.js.map +1 -0
- package/dist/engine/agent-api/GameEvidence.d.ts +1 -0
- package/dist/engine/agent-api/GameEvidence.d.ts.map +1 -1
- package/dist/engine/agent-api/GameEvidence.js +1 -0
- package/dist/engine/agent-api/GameEvidence.js.map +1 -1
- package/dist/engine/agent-api/GameGenreKits.d.ts +13 -0
- package/dist/engine/agent-api/GameGenreKits.d.ts.map +1 -1
- package/dist/engine/agent-api/GameGenreKits.js +57 -11
- package/dist/engine/agent-api/GameGenreKits.js.map +1 -1
- package/dist/engine/agent-api/GameRuntime.d.ts +1 -0
- package/dist/engine/agent-api/GameRuntime.d.ts.map +1 -1
- package/dist/engine/agent-api/GameRuntime.js +1 -0
- package/dist/engine/agent-api/GameRuntime.js.map +1 -1
- package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts +12 -0
- package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts.map +1 -1
- package/dist/engine/agent-api/GameSceneGeometryBindings.js +2 -0
- package/dist/engine/agent-api/GameSceneGeometryBindings.js.map +1 -1
- package/dist/engine/agent-api/LayeredSceneComposition.d.ts +295 -0
- package/dist/engine/agent-api/LayeredSceneComposition.d.ts.map +1 -0
- package/dist/engine/agent-api/LayeredSceneComposition.js +387 -0
- package/dist/engine/agent-api/LayeredSceneComposition.js.map +1 -0
- package/dist/engine/agent-api/SceneGroundingUtils.d.ts +62 -0
- package/dist/engine/agent-api/SceneGroundingUtils.d.ts.map +1 -1
- package/dist/engine/agent-api/SceneGroundingUtils.js +37 -0
- package/dist/engine/agent-api/SceneGroundingUtils.js.map +1 -1
- package/dist/engine/agent-api/SubjectFramingUtils.d.ts +127 -0
- package/dist/engine/agent-api/SubjectFramingUtils.d.ts.map +1 -0
- package/dist/engine/agent-api/SubjectFramingUtils.js +126 -0
- package/dist/engine/agent-api/SubjectFramingUtils.js.map +1 -0
- package/dist/engine/agent-api/TouchControlBinding.d.ts +81 -0
- package/dist/engine/agent-api/TouchControlBinding.d.ts.map +1 -0
- package/dist/engine/agent-api/TouchControlBinding.js +116 -0
- package/dist/engine/agent-api/TouchControlBinding.js.map +1 -0
- package/dist/engine/agent-api/index.d.ts +39 -0
- package/dist/engine/agent-api/index.d.ts.map +1 -1
- package/dist/engine/agent-api/index.js +546 -74
- package/dist/engine/agent-api/index.js.map +1 -1
- package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
- package/dist/engine/production-runtime/GameRenderPreset.d.ts +32 -0
- package/dist/engine/production-runtime/GameRenderPreset.d.ts.map +1 -1
- package/dist/engine/production-runtime/GameRenderPreset.js +37 -2
- package/dist/engine/production-runtime/GameRenderPreset.js.map +1 -1
- package/dist/engine/production-runtime/TypedGLBActor.d.ts +8 -0
- package/dist/engine/production-runtime/TypedGLBActor.d.ts.map +1 -1
- package/dist/engine/production-runtime/TypedGLBActor.js +2 -1
- package/dist/engine/production-runtime/TypedGLBActor.js.map +1 -1
- package/dist/input/controls/PointerLockControls.d.ts +1 -1
- package/dist/input/controls/PointerLockControls.d.ts.map +1 -1
- package/dist/input/controls/PointerLockControls.js +12 -0
- package/dist/input/controls/PointerLockControls.js.map +1 -1
- package/dist/physics/Collider.d.ts +1 -1
- package/dist/physics/Collider.d.ts.map +1 -1
- package/dist/physics/Collider.js +2 -2
- package/dist/physics/Collider.js.map +1 -1
- package/dist/physics/CollisionEvents.d.ts +1 -0
- package/dist/physics/CollisionEvents.d.ts.map +1 -1
- package/dist/physics/CollisionEvents.js.map +1 -1
- package/dist/physics/NarrowPhase.d.ts +11 -0
- package/dist/physics/NarrowPhase.d.ts.map +1 -0
- package/dist/physics/NarrowPhase.js +565 -0
- package/dist/physics/NarrowPhase.js.map +1 -0
- package/dist/physics/PhysicsDebugDraw.js +19 -1
- package/dist/physics/PhysicsDebugDraw.js.map +1 -1
- package/dist/physics/PhysicsWorld.d.ts +43 -0
- package/dist/physics/PhysicsWorld.d.ts.map +1 -1
- package/dist/physics/PhysicsWorld.js +305 -30
- package/dist/physics/PhysicsWorld.js.map +1 -1
- package/dist/physics/RigidBody.d.ts +8 -1
- package/dist/physics/RigidBody.d.ts.map +1 -1
- package/dist/physics/RigidBody.js +32 -5
- package/dist/physics/RigidBody.js.map +1 -1
- package/dist/physics/Shape.d.ts +16 -2
- package/dist/physics/Shape.d.ts.map +1 -1
- package/dist/physics/Shape.js +93 -31
- package/dist/physics/Shape.js.map +1 -1
- package/dist/physics/TimeOfImpact.d.ts +15 -0
- package/dist/physics/TimeOfImpact.d.ts.map +1 -0
- package/dist/physics/TimeOfImpact.js +81 -0
- package/dist/physics/TimeOfImpact.js.map +1 -0
- package/dist/physics/index.d.ts +2 -0
- package/dist/physics/index.d.ts.map +1 -1
- package/dist/physics/index.js +2 -0
- package/dist/physics/index.js.map +1 -1
- package/dist/rendering/CascadedShadowMaps.d.ts +9 -1
- package/dist/rendering/CascadedShadowMaps.d.ts.map +1 -1
- package/dist/rendering/CascadedShadowMaps.js +68 -0
- package/dist/rendering/CascadedShadowMaps.js.map +1 -1
- package/dist/rendering/ClusteredForwardLighting.d.ts +28 -0
- package/dist/rendering/ClusteredForwardLighting.d.ts.map +1 -0
- package/dist/rendering/ClusteredForwardLighting.js +156 -0
- package/dist/rendering/ClusteredForwardLighting.js.map +1 -0
- package/dist/rendering/DepthPass.d.ts +14 -1
- package/dist/rendering/DepthPass.d.ts.map +1 -1
- package/dist/rendering/DepthPass.js +19 -4
- package/dist/rendering/DepthPass.js.map +1 -1
- package/dist/rendering/EnvironmentMapResources.d.ts +59 -1
- package/dist/rendering/EnvironmentMapResources.d.ts.map +1 -1
- package/dist/rendering/EnvironmentMapResources.js +140 -100
- package/dist/rendering/EnvironmentMapResources.js.map +1 -1
- package/dist/rendering/EnvironmentPlatform.d.ts +3 -2
- package/dist/rendering/EnvironmentPlatform.d.ts.map +1 -1
- package/dist/rendering/EnvironmentPlatform.js +99 -44
- package/dist/rendering/EnvironmentPlatform.js.map +1 -1
- package/dist/rendering/ForwardPass.d.ts +37 -0
- package/dist/rendering/ForwardPass.d.ts.map +1 -1
- package/dist/rendering/ForwardPass.js +234 -7
- package/dist/rendering/ForwardPass.js.map +1 -1
- package/dist/rendering/Geometry.d.ts +19 -0
- package/dist/rendering/Geometry.d.ts.map +1 -1
- package/dist/rendering/Geometry.js +64 -0
- package/dist/rendering/Geometry.js.map +1 -1
- package/dist/rendering/IBL.d.ts.map +1 -1
- package/dist/rendering/IBL.js +0 -1
- package/dist/rendering/IBL.js.map +1 -1
- package/dist/rendering/LightCollector.d.ts +5 -1
- package/dist/rendering/LightCollector.d.ts.map +1 -1
- package/dist/rendering/LightCollector.js +16 -3
- package/dist/rendering/LightCollector.js.map +1 -1
- package/dist/rendering/LightUniforms.d.ts +26 -1
- package/dist/rendering/LightUniforms.d.ts.map +1 -1
- package/dist/rendering/LightUniforms.js +140 -8
- package/dist/rendering/LightUniforms.js.map +1 -1
- package/dist/rendering/LightingRig.d.ts +77 -0
- package/dist/rendering/LightingRig.d.ts.map +1 -1
- package/dist/rendering/LightingRig.js +100 -11
- package/dist/rendering/LightingRig.js.map +1 -1
- package/dist/rendering/MeshConsolidation.d.ts +63 -0
- package/dist/rendering/MeshConsolidation.d.ts.map +1 -0
- package/dist/rendering/MeshConsolidation.js +251 -0
- package/dist/rendering/MeshConsolidation.js.map +1 -0
- package/dist/rendering/PMREM.d.ts +13 -1
- package/dist/rendering/PMREM.d.ts.map +1 -1
- package/dist/rendering/PMREM.js +18 -4
- package/dist/rendering/PMREM.js.map +1 -1
- package/dist/rendering/PostProcessPass.d.ts +24 -2
- package/dist/rendering/PostProcessPass.d.ts.map +1 -1
- package/dist/rendering/PostProcessPass.js +136 -18
- package/dist/rendering/PostProcessPass.js.map +1 -1
- package/dist/rendering/PrimitiveSubmissionAudit.d.ts +195 -0
- package/dist/rendering/PrimitiveSubmissionAudit.d.ts.map +1 -0
- package/dist/rendering/PrimitiveSubmissionAudit.js +280 -0
- package/dist/rendering/PrimitiveSubmissionAudit.js.map +1 -0
- package/dist/rendering/ProductTurntableFixtures.d.ts.map +1 -1
- package/dist/rendering/ProductTurntableFixtures.js +93 -13
- package/dist/rendering/ProductTurntableFixtures.js.map +1 -1
- package/dist/rendering/ReflectionProbe.d.ts +59 -0
- package/dist/rendering/ReflectionProbe.d.ts.map +1 -1
- package/dist/rendering/ReflectionProbe.js +224 -0
- package/dist/rendering/ReflectionProbe.js.map +1 -1
- package/dist/rendering/ReflectionSurfaces.d.ts +4 -2
- package/dist/rendering/ReflectionSurfaces.d.ts.map +1 -1
- package/dist/rendering/ReflectionSurfaces.js +13 -8
- package/dist/rendering/ReflectionSurfaces.js.map +1 -1
- package/dist/rendering/RenderBackend.d.ts +1 -1
- package/dist/rendering/RenderBackend.d.ts.map +1 -1
- package/dist/rendering/RenderBackend.js +5 -1
- package/dist/rendering/RenderBackend.js.map +1 -1
- package/dist/rendering/RenderDevice.d.ts +13 -2
- package/dist/rendering/RenderDevice.d.ts.map +1 -1
- package/dist/rendering/RenderDevice.js +5 -2
- package/dist/rendering/RenderDevice.js.map +1 -1
- package/dist/rendering/Renderer.d.ts +41 -1
- package/dist/rendering/Renderer.d.ts.map +1 -1
- package/dist/rendering/Renderer.js +406 -61
- package/dist/rendering/Renderer.js.map +1 -1
- package/dist/rendering/RendererPostprocessPlan.d.ts +10 -3
- package/dist/rendering/RendererPostprocessPlan.d.ts.map +1 -1
- package/dist/rendering/RendererPostprocessPlan.js +25 -5
- package/dist/rendering/RendererPostprocessPlan.js.map +1 -1
- package/dist/rendering/RendererVisualPipelineReport.d.ts +3 -2
- package/dist/rendering/RendererVisualPipelineReport.d.ts.map +1 -1
- package/dist/rendering/RendererVisualPipelineReport.js +2 -0
- package/dist/rendering/RendererVisualPipelineReport.js.map +1 -1
- package/dist/rendering/ScreenSpaceLineMaterial.d.ts +34 -0
- package/dist/rendering/ScreenSpaceLineMaterial.d.ts.map +1 -0
- package/dist/rendering/ScreenSpaceLineMaterial.js +93 -0
- package/dist/rendering/ScreenSpaceLineMaterial.js.map +1 -0
- package/dist/rendering/ShaderChunks.d.ts +7 -0
- package/dist/rendering/ShaderChunks.d.ts.map +1 -1
- package/dist/rendering/ShaderChunks.js +137 -0
- package/dist/rendering/ShaderChunks.js.map +1 -1
- package/dist/rendering/ShaderLibrary.d.ts +17 -0
- package/dist/rendering/ShaderLibrary.d.ts.map +1 -1
- package/dist/rendering/ShaderLibrary.js +940 -98
- package/dist/rendering/ShaderLibrary.js.map +1 -1
- package/dist/rendering/ShadowPass.d.ts +10 -0
- package/dist/rendering/ShadowPass.d.ts.map +1 -1
- package/dist/rendering/ShadowPass.js +8 -1
- package/dist/rendering/ShadowPass.js.map +1 -1
- package/dist/rendering/SkinnedLitMaterial.d.ts +6 -0
- package/dist/rendering/SkinnedLitMaterial.d.ts.map +1 -1
- package/dist/rendering/SkinnedLitMaterial.js +22 -8
- package/dist/rendering/SkinnedLitMaterial.js.map +1 -1
- package/dist/rendering/SkinnedUnlitMaterial.d.ts +8 -0
- package/dist/rendering/SkinnedUnlitMaterial.d.ts.map +1 -1
- package/dist/rendering/SkinnedUnlitMaterial.js +26 -9
- package/dist/rendering/SkinnedUnlitMaterial.js.map +1 -1
- package/dist/rendering/SpecularPrefilter.d.ts +42 -0
- package/dist/rendering/SpecularPrefilter.d.ts.map +1 -0
- package/dist/rendering/SpecularPrefilter.js +480 -0
- package/dist/rendering/SpecularPrefilter.js.map +1 -0
- package/dist/rendering/TerrainFixtures.d.ts +24 -0
- package/dist/rendering/TerrainFixtures.d.ts.map +1 -1
- package/dist/rendering/TerrainFixtures.js +96 -0
- package/dist/rendering/TerrainFixtures.js.map +1 -1
- package/dist/rendering/Texture.d.ts +7 -0
- package/dist/rendering/Texture.d.ts.map +1 -1
- package/dist/rendering/Texture.js +9 -0
- package/dist/rendering/Texture.js.map +1 -1
- package/dist/rendering/VertexFormat.d.ts +34 -1
- package/dist/rendering/VertexFormat.d.ts.map +1 -1
- package/dist/rendering/VertexFormat.js +61 -0
- package/dist/rendering/VertexFormat.js.map +1 -1
- package/dist/rendering/WebGL2Device.d.ts +48 -0
- package/dist/rendering/WebGL2Device.d.ts.map +1 -1
- package/dist/rendering/WebGL2Device.js +1298 -44
- package/dist/rendering/WebGL2Device.js.map +1 -1
- package/dist/rendering/WebGPUDevice.d.ts +7 -2
- package/dist/rendering/WebGPUDevice.d.ts.map +1 -1
- package/dist/rendering/WebGPUDevice.js +111 -17
- package/dist/rendering/WebGPUDevice.js.map +1 -1
- package/dist/rendering/WebGPUSkinningLimits.d.ts +14 -0
- package/dist/rendering/WebGPUSkinningLimits.d.ts.map +1 -0
- package/dist/rendering/WebGPUSkinningLimits.js +14 -0
- package/dist/rendering/WebGPUSkinningLimits.js.map +1 -0
- package/dist/rendering/cartoon/CartoonMaterialStyle.d.ts +19 -0
- package/dist/rendering/cartoon/CartoonMaterialStyle.d.ts.map +1 -0
- package/dist/rendering/cartoon/CartoonMaterialStyle.js +13 -0
- package/dist/rendering/cartoon/CartoonMaterialStyle.js.map +1 -0
- package/dist/rendering/cartoon/CartoonRenderPreset.d.ts +36 -0
- package/dist/rendering/cartoon/CartoonRenderPreset.d.ts.map +1 -0
- package/dist/rendering/cartoon/CartoonRenderPreset.js +23 -0
- package/dist/rendering/cartoon/CartoonRenderPreset.js.map +1 -0
- package/dist/rendering/cartoon/CartoonToonMaterial.d.ts +130 -0
- package/dist/rendering/cartoon/CartoonToonMaterial.d.ts.map +1 -0
- package/dist/rendering/cartoon/CartoonToonMaterial.js +303 -0
- package/dist/rendering/cartoon/CartoonToonMaterial.js.map +1 -0
- package/dist/rendering/cartoon/CartoonVisualQuality.d.ts +28 -0
- package/dist/rendering/cartoon/CartoonVisualQuality.d.ts.map +1 -0
- package/dist/rendering/cartoon/CartoonVisualQuality.js +39 -0
- package/dist/rendering/cartoon/CartoonVisualQuality.js.map +1 -0
- package/dist/rendering/cartoon/applyCartoonRenderPreset.d.ts +79 -0
- package/dist/rendering/cartoon/applyCartoonRenderPreset.d.ts.map +1 -0
- package/dist/rendering/cartoon/applyCartoonRenderPreset.js +88 -0
- package/dist/rendering/cartoon/applyCartoonRenderPreset.js.map +1 -0
- package/dist/rendering/cartoon/index.d.ts +6 -0
- package/dist/rendering/cartoon/index.d.ts.map +1 -0
- package/dist/rendering/cartoon/index.js +6 -0
- package/dist/rendering/cartoon/index.js.map +1 -0
- package/dist/rendering/index.d.ts +26 -15
- package/dist/rendering/index.d.ts.map +1 -1
- package/dist/rendering/index.js +15 -9
- package/dist/rendering/index.js.map +1 -1
- package/dist/rendering/postprocess/NativeLdrEffectLuts.d.ts +93 -0
- package/dist/rendering/postprocess/NativeLdrEffectLuts.d.ts.map +1 -0
- package/dist/rendering/postprocess/NativeLdrEffectLuts.js +202 -0
- package/dist/rendering/postprocess/NativeLdrEffectLuts.js.map +1 -0
- package/dist/rendering/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
- package/dist/rendering/production-runtime/PBRHDRPipeline.js +3 -0
- package/dist/rendering/production-runtime/PBRHDRPipeline.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts +1 -0
- package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionRendererTypes.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js +5 -3
- package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.js +9 -5
- package/dist/rendering/production-runtime/ProductionWebGPURenderer.js.map +1 -1
- package/dist/rendering/production-runtime/TransmissionBackdropCapture.d.ts +5 -0
- package/dist/rendering/production-runtime/TransmissionBackdropCapture.d.ts.map +1 -1
- package/dist/rendering/production-runtime/TransmissionBackdropCapture.js +40 -0
- package/dist/rendering/production-runtime/TransmissionBackdropCapture.js.map +1 -1
- package/dist/rendering/production-runtime/environment/HDRLoader.d.ts +6 -0
- package/dist/rendering/production-runtime/environment/HDRLoader.d.ts.map +1 -1
- package/dist/rendering/production-runtime/environment/HDRLoader.js +19 -0
- package/dist/rendering/production-runtime/environment/HDRLoader.js.map +1 -1
- package/dist/rendering/production-runtime/index.d.ts +3 -1
- package/dist/rendering/production-runtime/index.d.ts.map +1 -1
- package/dist/rendering/production-runtime/index.js +1 -0
- package/dist/rendering/production-runtime/index.js.map +1 -1
- package/dist/scene/Light.d.ts +1 -1
- package/dist/scene/Light.d.ts.map +1 -1
- package/dist/scene/RectAreaLight.d.ts +22 -0
- package/dist/scene/RectAreaLight.d.ts.map +1 -0
- package/dist/scene/RectAreaLight.js +46 -0
- package/dist/scene/RectAreaLight.js.map +1 -0
- package/dist/scene/Scene.d.ts +6 -1
- package/dist/scene/Scene.d.ts.map +1 -1
- package/dist/scene/Scene.js +8 -1
- package/dist/scene/Scene.js.map +1 -1
- package/dist/scene/SceneSerializer.d.ts +3 -1
- package/dist/scene/SceneSerializer.d.ts.map +1 -1
- package/dist/scene/SceneSerializer.js +14 -7
- package/dist/scene/SceneSerializer.js.map +1 -1
- package/dist/scene/index.d.ts +1 -0
- package/dist/scene/index.d.ts.map +1 -1
- package/dist/scene/index.js +1 -0
- package/dist/scene/index.js.map +1 -1
- package/dist/scripting/CartoonNodeCategories.d.ts +3 -0
- package/dist/scripting/CartoonNodeCategories.d.ts.map +1 -0
- package/dist/scripting/CartoonNodeCategories.js +9 -0
- package/dist/scripting/CartoonNodeCategories.js.map +1 -0
- package/dist/scripting/CartoonVisualNodes.d.ts +3 -0
- package/dist/scripting/CartoonVisualNodes.d.ts.map +1 -0
- package/dist/scripting/CartoonVisualNodes.js +41 -0
- package/dist/scripting/CartoonVisualNodes.js.map +1 -0
- package/package.json +124 -113
- package/templates/cinematic-scene/package.json +1 -1
- package/templates/mini-game/package.json +1 -1
- package/templates/product-viewer/package.json +1 -1
- package/templates/production-asset-inspector/README.md +5 -0
- package/templates/production-asset-inspector/asset-manifest.json +9 -0
- package/templates/production-asset-inspector/index.html +2 -0
- package/templates/production-asset-inspector/package.json +17 -0
- package/templates/production-asset-inspector/src/main.ts +16 -0
- package/templates/production-material-studio/README.md +5 -0
- package/templates/production-material-studio/asset-manifest.json +9 -0
- package/templates/production-material-studio/index.html +2 -0
- package/templates/production-material-studio/package.json +17 -0
- package/templates/production-material-studio/src/main.ts +16 -0
- package/templates/production-product-configurator/README.md +5 -0
- package/templates/production-product-configurator/asset-manifest.json +9 -0
- package/templates/production-product-configurator/index.html +2 -0
- package/templates/production-product-configurator/package.json +17 -0
- package/templates/production-product-configurator/src/main.ts +16 -0
- package/templates/production-product-viewer/README.md +7 -0
- package/templates/production-product-viewer/asset-manifest.json +8 -0
- package/templates/production-product-viewer/index.html +26 -0
- package/templates/production-product-viewer/package.json +17 -0
- package/templates/production-product-viewer/src/main.ts +70 -0
|
@@ -108,6 +108,16 @@ export const DEFAULT_SKINNED_UNLIT_SHADER_NAME = "aura3d/skinned-unlit";
|
|
|
108
108
|
export const DEFAULT_SKINNED_UNLIT_SHADER_MARKER = "@aura3d-shader:skinned-unlit";
|
|
109
109
|
export const DEFAULT_SKINNED_LIT_SHADER_NAME = "aura3d/skinned-lit";
|
|
110
110
|
export const DEFAULT_SKINNED_LIT_SHADER_MARKER = "@aura3d-shader:skinned-lit";
|
|
111
|
+
/**
|
|
112
|
+
* Eight-influence skinned shaders. These read a second `JOINTS_1`/`WEIGHTS_1`
|
|
113
|
+
* attribute set and select between uniform-array and data-texture joint palettes at
|
|
114
|
+
* runtime through `u_jointPaletteMode`, so a single program serves both small rigs
|
|
115
|
+
* and rigs above the uniform-array joint limit.
|
|
116
|
+
*/
|
|
117
|
+
export const DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_NAME = "aura3d/skinned-unlit-8";
|
|
118
|
+
export const DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_MARKER = "@aura3d-shader:skinned-unlit-8";
|
|
119
|
+
export const DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_NAME = "aura3d/skinned-lit-8";
|
|
120
|
+
export const DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_MARKER = "@aura3d-shader:skinned-lit-8";
|
|
111
121
|
export const DEFAULT_MORPH_UNLIT_SHADER_NAME = "aura3d/morph-unlit";
|
|
112
122
|
export const DEFAULT_MORPH_UNLIT_SHADER_MARKER = "@aura3d-shader:morph-unlit";
|
|
113
123
|
export const DEFAULT_NORMAL_MAPPED_PBR_SHADER_NAME = "aura3d/pbr-normal-map";
|
|
@@ -121,6 +131,13 @@ export const DEFAULT_TEXTURED_PBR_IRIDESCENCE_TEXTURES_VARIANT = "iridescence-te
|
|
|
121
131
|
export const DEFAULT_TEXTURED_PBR_CLEARCOAT_TRANSMISSION_VOLUME_TEXTURES_VARIANT = "clearcoat-transmission-volume-textures";
|
|
122
132
|
export const DEFAULT_TEXTURED_PBR_CLEARCOAT_SPECULAR_TEXTURES_VARIANT = "clearcoat-specular-textures";
|
|
123
133
|
export const DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_IRIDESCENCE_TEXTURES_VARIANT = "specular-sheen-anisotropy-iridescence-textures";
|
|
134
|
+
/**
|
|
135
|
+
* True screen-space fat lines, equivalent in intent to Three.js `Line2`/`LineMaterial`.
|
|
136
|
+
* Width is specified in pixels and stays constant across distance, FOV, viewport size,
|
|
137
|
+
* and device pixel ratio.
|
|
138
|
+
*/
|
|
139
|
+
export const DEFAULT_SCREEN_SPACE_LINE_SHADER_NAME = "aura3d/screen-space-line";
|
|
140
|
+
export const DEFAULT_SCREEN_SPACE_LINE_SHADER_MARKER = "@aura3d-shader:screen-space-line";
|
|
124
141
|
export const DEFAULT_DEPTH_SHADER_NAME = "aura3d/depth";
|
|
125
142
|
export const DEFAULT_DEPTH_SHADER_MARKER = "@aura3d-shader:depth";
|
|
126
143
|
export const DEFAULT_ENVIRONMENT_BACKGROUND_SHADER_NAME = "aura3d/environment-background";
|
|
@@ -287,7 +304,12 @@ uniform float u_iridescenceThicknessMinimum;
|
|
|
287
304
|
uniform float u_iridescenceThicknessMaximum;
|
|
288
305
|
uniform float u_dispersion;
|
|
289
306
|
uniform float u_lightCount;
|
|
290
|
-
uniform vec4 u_lightData[
|
|
307
|
+
uniform vec4 u_lightData[96];
|
|
308
|
+
uniform float u_clusteredLightEnabled;
|
|
309
|
+
uniform vec2 u_clusterGridSize;
|
|
310
|
+
uniform vec2 u_clusterViewportSize;
|
|
311
|
+
uniform sampler2D u_clusterLightData;
|
|
312
|
+
uniform sampler2D u_clusterLightIndices;
|
|
291
313
|
uniform sampler2D u_shadowMapTexture;
|
|
292
314
|
uniform float u_shadowMapEnabled;
|
|
293
315
|
uniform mat4 u_shadowMapMatrix;
|
|
@@ -396,8 +418,18 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
396
418
|
vec3 receiverNormal = normalize(normal);
|
|
397
419
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
398
420
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
399
|
-
|
|
400
|
-
|
|
421
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
422
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
423
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
424
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
425
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
426
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
427
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
428
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
429
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
430
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
431
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
432
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
401
433
|
float shadowed = 0.0;
|
|
402
434
|
float totalWeight = 0.0;
|
|
403
435
|
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
@@ -407,6 +439,8 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
407
439
|
float weight = max(sampleData.z, 0.0);
|
|
408
440
|
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
409
441
|
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
442
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
443
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
410
444
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
411
445
|
totalWeight += weight;
|
|
412
446
|
}
|
|
@@ -434,8 +468,18 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
434
468
|
vec3 receiverNormal = normalize(normal);
|
|
435
469
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
436
470
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
437
|
-
|
|
438
|
-
|
|
471
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
472
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
473
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
474
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
475
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
476
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
477
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
478
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
479
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
480
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
481
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
482
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
439
483
|
float shadowed = 0.0;
|
|
440
484
|
float totalWeight = 0.0;
|
|
441
485
|
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
@@ -445,6 +489,8 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
445
489
|
float weight = max(sampleData.z, 0.0);
|
|
446
490
|
vec2 offset = sampleData.xy * u_pointShadowTexelSize;
|
|
447
491
|
float storedDepth = texture(u_pointShadowMapTexture, uv + offset).r;
|
|
492
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
493
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
448
494
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
449
495
|
totalWeight += weight;
|
|
450
496
|
}
|
|
@@ -492,11 +538,16 @@ void main() {
|
|
|
492
538
|
float horizonBlend = 1.0 - abs(normal.y);
|
|
493
539
|
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
494
540
|
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
495
|
-
|
|
541
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
542
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
543
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
544
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
545
|
+
// separate physical contributions, so they sum.
|
|
546
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
496
547
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
497
548
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
498
549
|
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
499
|
-
environmentDiffuse = mix(environmentDiffuse,
|
|
550
|
+
environmentDiffuse = mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
500
551
|
vec3 reflectionDirection = reflect(-viewDirection, normal);
|
|
501
552
|
float roughness = clamp(u_roughness, 0.0, 1.0);
|
|
502
553
|
float reflectionBand = pow(clamp(reflectionDirection.y * 0.5 + 0.5, 0.0, 1.0), mix(18.0, 2.0, roughness));
|
|
@@ -556,14 +607,29 @@ void main() {
|
|
|
556
607
|
vec3 refractionRadiance = (refractedEnvironment + vec3(causticEnergy)) * volumeTint * u_environmentMapTextureIntensity * transmissionAmount * fallbackEnvironmentTransmissionEnergy * mix(0.9, 0.55, roughness) * roughVolumeIorLift;
|
|
557
608
|
shaded = mix(shaded, shaded * 0.72 + refractionRadiance, transmissionAmount * mix(0.08, 0.58, fallbackEnvironmentTransmissionEnergy));
|
|
558
609
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
610
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
611
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
612
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
613
|
+
for (int i = 0; i < 64; ++i) {
|
|
614
|
+
if (i >= count) break;
|
|
615
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
616
|
+
int baseIndex = lightIndex * 6;
|
|
617
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
618
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
619
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
620
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
621
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
622
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
566
623
|
float kind = directionKind.w;
|
|
624
|
+
if (kind > 2.5) {
|
|
625
|
+
shaded += a3dPbrRectAreaLight(
|
|
626
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
627
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
628
|
+
normal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
629
|
+
materialBase, u_metallic, u_roughness, u_specularFactor, u_specularColorFactor
|
|
630
|
+
);
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
567
633
|
vec3 lightDirection = -directionKind.xyz;
|
|
568
634
|
float attenuation = 1.0;
|
|
569
635
|
if (kind > 0.5) {
|
|
@@ -684,7 +750,12 @@ uniform float u_environmentBrdfLutEnabled;
|
|
|
684
750
|
uniform vec3 u_emissiveColor;
|
|
685
751
|
uniform float u_emissiveStrength;
|
|
686
752
|
uniform float u_lightCount;
|
|
687
|
-
uniform vec4 u_lightData[
|
|
753
|
+
uniform vec4 u_lightData[96];
|
|
754
|
+
uniform float u_clusteredLightEnabled;
|
|
755
|
+
uniform vec2 u_clusterGridSize;
|
|
756
|
+
uniform vec2 u_clusterViewportSize;
|
|
757
|
+
uniform sampler2D u_clusterLightData;
|
|
758
|
+
uniform sampler2D u_clusterLightIndices;
|
|
688
759
|
uniform sampler2D u_shadowMapTexture;
|
|
689
760
|
uniform float u_shadowMapEnabled;
|
|
690
761
|
uniform mat4 u_shadowMapMatrix;
|
|
@@ -731,8 +802,18 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
731
802
|
vec3 receiverNormal = normalize(normal);
|
|
732
803
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
733
804
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
734
|
-
|
|
735
|
-
|
|
805
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
806
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
807
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
808
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
809
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
810
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
811
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
812
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
813
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
814
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
815
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
816
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
736
817
|
float shadowed = 0.0;
|
|
737
818
|
float totalWeight = 0.0;
|
|
738
819
|
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
@@ -742,6 +823,8 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
742
823
|
float weight = max(sampleData.z, 0.0);
|
|
743
824
|
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
744
825
|
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
826
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
827
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
745
828
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
746
829
|
totalWeight += weight;
|
|
747
830
|
}
|
|
@@ -760,7 +843,12 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
760
843
|
vec4 rect = u_pointShadowFaceRects[faceIndex];
|
|
761
844
|
vec2 uv = rect.xy + localUv * rect.zw;
|
|
762
845
|
float normalDotLight = clamp(abs(dot(normalize(normal), normalize(lightDirection))), 0.0, 1.0);
|
|
763
|
-
|
|
846
|
+
// Same per-sample, tangent-scaled slope bias as the directional and atlas paths. These
|
|
847
|
+
// cubemap-face variants inline the sample fetch, but they share the identical acne
|
|
848
|
+
// mechanism: a centre-only, (1 - N.L)-scaled bias under-compensates every outer tap.
|
|
849
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
850
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
851
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
764
852
|
float shadowed = 0.0;
|
|
765
853
|
float totalWeight = 0.0;
|
|
766
854
|
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
@@ -768,6 +856,8 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
768
856
|
if (i >= sampleCount) break;
|
|
769
857
|
vec4 sampleData = u_pointShadowPcfSamples[i];
|
|
770
858
|
float weight = max(sampleData.z, 0.0);
|
|
859
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
860
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
771
861
|
shadowed += (receiverDepth > texture(u_pointShadowMapTexture, uv + sampleData.xy * u_pointShadowTexelSize).r ? 1.0 : 0.0) * weight;
|
|
772
862
|
totalWeight += weight;
|
|
773
863
|
}
|
|
@@ -827,11 +917,16 @@ vec3 a3dPbrEnvironmentDiffuseInput(vec3 normal) {
|
|
|
827
917
|
float horizonBlend = 1.0 - abs(normal.y);
|
|
828
918
|
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
829
919
|
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
830
|
-
|
|
920
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
921
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
922
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
923
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
924
|
+
// separate physical contributions, so they sum.
|
|
925
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
831
926
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
832
927
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
833
928
|
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
834
|
-
return mix(environmentDiffuse,
|
|
929
|
+
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
835
930
|
}
|
|
836
931
|
vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
837
932
|
float proceduralEnvironmentWeight = step(0.0001, u_environmentMapIntensity);
|
|
@@ -852,11 +947,15 @@ vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float rough
|
|
|
852
947
|
float environmentLod = clampedRoughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
853
948
|
vec3 sampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
854
949
|
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
855
|
-
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clampedRoughness)).rg;
|
|
856
950
|
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
857
951
|
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
858
952
|
return proceduralSpecular + sampledSpecular;
|
|
859
953
|
}
|
|
954
|
+
vec2 a3dPbrEnvironmentBrdfInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
955
|
+
float nDotV = clamp(dot(normalize(normal), normalize(viewDirection)), 0.0, 1.0);
|
|
956
|
+
vec2 lut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clamp(roughness, 0.0, 1.0))).rg;
|
|
957
|
+
return mix(vec2(1.0, 0.0), lut, step(0.0001, u_environmentBrdfLutEnabled));
|
|
958
|
+
}
|
|
860
959
|
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
861
960
|
vec3 color = max(linearColor, vec3(0.0));
|
|
862
961
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
@@ -868,25 +967,41 @@ void main() {
|
|
|
868
967
|
if (!gl_FrontFacing) normal = -normal;
|
|
869
968
|
vec3 viewDirection = normalize(u_cameraPosition - v_worldPosition);
|
|
870
969
|
vec3 base = u_baseColor.rgb * v_instanceColor.rgb;
|
|
871
|
-
vec3 shaded = u_emissiveColor * u_emissiveStrength +
|
|
970
|
+
vec3 shaded = u_emissiveColor * u_emissiveStrength + a3dPbrEnvironmentLightSplitSum(
|
|
872
971
|
normal,
|
|
873
972
|
viewDirection,
|
|
874
973
|
a3dPbrEnvironmentDiffuseInput(normal),
|
|
875
974
|
a3dPbrEnvironmentSpecularInput(normal, viewDirection, u_roughness),
|
|
975
|
+
a3dPbrEnvironmentBrdfInput(normal, viewDirection, u_roughness),
|
|
876
976
|
base,
|
|
877
977
|
u_metallic,
|
|
878
978
|
u_roughness,
|
|
879
979
|
1.0,
|
|
880
980
|
vec3(1.0)
|
|
881
981
|
);
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
982
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
983
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
984
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
985
|
+
for (int i = 0; i < 64; ++i) {
|
|
986
|
+
if (i >= count) break;
|
|
987
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
988
|
+
int baseIndex = lightIndex * 6;
|
|
989
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
990
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
991
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
992
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
993
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
994
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
889
995
|
float kind = directionKind.w;
|
|
996
|
+
if (kind > 2.5) {
|
|
997
|
+
shaded += a3dPbrRectAreaLight(
|
|
998
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
999
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
1000
|
+
normal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
1001
|
+
base, u_metallic, u_roughness, 1.0, vec3(1.0)
|
|
1002
|
+
);
|
|
1003
|
+
continue;
|
|
1004
|
+
}
|
|
890
1005
|
vec3 lightDirection = -directionKind.xyz;
|
|
891
1006
|
float attenuation = 1.0;
|
|
892
1007
|
if (kind > 0.5) {
|
|
@@ -961,23 +1076,13 @@ void main() {
|
|
|
961
1076
|
vertex: `#version 300 es
|
|
962
1077
|
// ${DEFAULT_SKINNED_UNLIT_SHADER_MARKER}
|
|
963
1078
|
precision highp float;
|
|
1079
|
+
#include <skinning_common>
|
|
964
1080
|
layout(location = 0) in vec3 a_position;
|
|
965
1081
|
layout(location = 5) in vec4 a_joints;
|
|
966
1082
|
layout(location = 6) in vec4 a_weights;
|
|
967
1083
|
uniform mat4 u_modelViewProjection;
|
|
968
|
-
uniform mat4 u_jointMatrices[96];
|
|
969
|
-
uniform float u_jointCount;
|
|
970
1084
|
void main() {
|
|
971
|
-
|
|
972
|
-
int jointX = int(clamp(a_joints.x, 0.0, maxJoint));
|
|
973
|
-
int jointY = int(clamp(a_joints.y, 0.0, maxJoint));
|
|
974
|
-
int jointZ = int(clamp(a_joints.z, 0.0, maxJoint));
|
|
975
|
-
int jointW = int(clamp(a_joints.w, 0.0, maxJoint));
|
|
976
|
-
mat4 skin =
|
|
977
|
-
u_jointMatrices[jointX] * a_weights.x +
|
|
978
|
-
u_jointMatrices[jointY] * a_weights.y +
|
|
979
|
-
u_jointMatrices[jointZ] * a_weights.z +
|
|
980
|
-
u_jointMatrices[jointW] * a_weights.w;
|
|
1085
|
+
mat4 skin = a3dSkinMatrix4(a_joints, a_weights);
|
|
981
1086
|
float weightSum = a_weights.x + a_weights.y + a_weights.z + a_weights.w;
|
|
982
1087
|
vec4 skinnedPosition = weightSum > 0.0001 ? skin * vec4(a_position, 1.0) : vec4(a_position, 1.0);
|
|
983
1088
|
gl_Position = u_modelViewProjection * skinnedPosition;
|
|
@@ -999,6 +1104,7 @@ void main() {
|
|
|
999
1104
|
vertex: `#version 300 es
|
|
1000
1105
|
// ${DEFAULT_SKINNED_LIT_SHADER_MARKER}
|
|
1001
1106
|
precision highp float;
|
|
1107
|
+
#include <skinning_common>
|
|
1002
1108
|
layout(location = 0) in vec3 a_position;
|
|
1003
1109
|
layout(location = 1) in vec3 a_normal;
|
|
1004
1110
|
layout(location = 2) in vec2 a_uv;
|
|
@@ -1012,8 +1118,6 @@ uniform mat4 u_normalMatrix;
|
|
|
1012
1118
|
uniform vec2 u_baseColorTextureOffset;
|
|
1013
1119
|
uniform vec2 u_baseColorTextureScale;
|
|
1014
1120
|
uniform float u_baseColorTextureRotation;
|
|
1015
|
-
uniform mat4 u_jointMatrices[96];
|
|
1016
|
-
uniform float u_jointCount;
|
|
1017
1121
|
out vec3 v_normal;
|
|
1018
1122
|
out vec4 v_tangent;
|
|
1019
1123
|
out vec3 v_worldPosition;
|
|
@@ -1026,16 +1130,7 @@ void main() {
|
|
|
1026
1130
|
float s = sin(u_baseColorTextureRotation);
|
|
1027
1131
|
v_uv = vec2(scaledUv.x * c - scaledUv.y * s, scaledUv.x * s + scaledUv.y * c) + u_baseColorTextureOffset;
|
|
1028
1132
|
v_vertexColor = a_color;
|
|
1029
|
-
|
|
1030
|
-
int jointX = int(clamp(a_joints.x, 0.0, maxJoint));
|
|
1031
|
-
int jointY = int(clamp(a_joints.y, 0.0, maxJoint));
|
|
1032
|
-
int jointZ = int(clamp(a_joints.z, 0.0, maxJoint));
|
|
1033
|
-
int jointW = int(clamp(a_joints.w, 0.0, maxJoint));
|
|
1034
|
-
mat4 skin =
|
|
1035
|
-
u_jointMatrices[jointX] * a_weights.x +
|
|
1036
|
-
u_jointMatrices[jointY] * a_weights.y +
|
|
1037
|
-
u_jointMatrices[jointZ] * a_weights.z +
|
|
1038
|
-
u_jointMatrices[jointW] * a_weights.w;
|
|
1133
|
+
mat4 skin = a3dSkinMatrix4(a_joints, a_weights);
|
|
1039
1134
|
v_weightSum = a_weights.x + a_weights.y + a_weights.z + a_weights.w;
|
|
1040
1135
|
vec4 skinnedPosition = v_weightSum > 0.0001 ? skin * vec4(a_position, 1.0) : vec4(a_position, 1.0);
|
|
1041
1136
|
vec3 skinnedNormal = (v_weightSum > 0.0001 ? skin * vec4(a_normal, 0.0) : vec4(a_normal, 0.0)).xyz;
|
|
@@ -1115,7 +1210,12 @@ uniform float u_iridescenceThicknessMinimum;
|
|
|
1115
1210
|
uniform float u_iridescenceThicknessMaximum;
|
|
1116
1211
|
uniform float u_dispersion;
|
|
1117
1212
|
uniform float u_lightCount;
|
|
1118
|
-
uniform vec4 u_lightData[
|
|
1213
|
+
uniform vec4 u_lightData[96];
|
|
1214
|
+
uniform float u_clusteredLightEnabled;
|
|
1215
|
+
uniform vec2 u_clusterGridSize;
|
|
1216
|
+
uniform vec2 u_clusterViewportSize;
|
|
1217
|
+
uniform sampler2D u_clusterLightData;
|
|
1218
|
+
uniform sampler2D u_clusterLightIndices;
|
|
1119
1219
|
uniform sampler2D u_shadowMapTexture;
|
|
1120
1220
|
uniform float u_shadowMapEnabled;
|
|
1121
1221
|
uniform mat4 u_shadowMapMatrix;
|
|
@@ -1217,8 +1317,18 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
1217
1317
|
vec3 receiverNormal = normalize(normal);
|
|
1218
1318
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1219
1319
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1220
|
-
|
|
1221
|
-
|
|
1320
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
1321
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
1322
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
1323
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
1324
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
1325
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
1326
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
1327
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
1328
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
1329
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
1330
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
1331
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1222
1332
|
float shadowed = 0.0;
|
|
1223
1333
|
float totalWeight = 0.0;
|
|
1224
1334
|
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
@@ -1228,6 +1338,8 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
1228
1338
|
float weight = max(sampleData.z, 0.0);
|
|
1229
1339
|
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
1230
1340
|
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
1341
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
1342
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
1231
1343
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1232
1344
|
totalWeight += weight;
|
|
1233
1345
|
}
|
|
@@ -1255,8 +1367,18 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
1255
1367
|
vec3 receiverNormal = normalize(normal);
|
|
1256
1368
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1257
1369
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1258
|
-
|
|
1259
|
-
|
|
1370
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
1371
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
1372
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
1373
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
1374
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
1375
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
1376
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
1377
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
1378
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
1379
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
1380
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
1381
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1260
1382
|
float shadowed = 0.0;
|
|
1261
1383
|
float totalWeight = 0.0;
|
|
1262
1384
|
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
@@ -1266,6 +1388,8 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
1266
1388
|
float weight = max(sampleData.z, 0.0);
|
|
1267
1389
|
vec2 offset = sampleData.xy * u_pointShadowTexelSize;
|
|
1268
1390
|
float storedDepth = texture(u_pointShadowMapTexture, uv + offset).r;
|
|
1391
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
1392
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
1269
1393
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1270
1394
|
totalWeight += weight;
|
|
1271
1395
|
}
|
|
@@ -1323,7 +1447,12 @@ void main() {
|
|
|
1323
1447
|
float horizonBlend = 1.0 - abs(normal.y);
|
|
1324
1448
|
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
1325
1449
|
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
1326
|
-
|
|
1450
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
1451
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
1452
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
1453
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
1454
|
+
// separate physical contributions, so they sum.
|
|
1455
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
1327
1456
|
vec3 reflectionDirection = reflect(-viewDirection, normal);
|
|
1328
1457
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
1329
1458
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
@@ -1349,7 +1478,7 @@ void main() {
|
|
|
1349
1478
|
vec3 shaded = a3dPbrEnvironmentLightSplitSum(
|
|
1350
1479
|
normal,
|
|
1351
1480
|
viewDirection,
|
|
1352
|
-
mix(environmentDiffuse,
|
|
1481
|
+
mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight),
|
|
1353
1482
|
proceduralSpecular + sampledSpecular,
|
|
1354
1483
|
mix(vec2(1.0, 0.0), brdfLut, step(0.0001, u_environmentBrdfLutEnabled)),
|
|
1355
1484
|
materialBase,
|
|
@@ -1358,14 +1487,516 @@ void main() {
|
|
|
1358
1487
|
u_specularFactor,
|
|
1359
1488
|
u_specularColorFactor
|
|
1360
1489
|
) * occlusion + emissive;
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1490
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
1491
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
1492
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
1493
|
+
for (int i = 0; i < 64; ++i) {
|
|
1494
|
+
if (i >= count) break;
|
|
1495
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
1496
|
+
int baseIndex = lightIndex * 6;
|
|
1497
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
1498
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
1499
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
1500
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
1501
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
1502
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
1368
1503
|
float kind = directionKind.w;
|
|
1504
|
+
if (kind > 2.5) {
|
|
1505
|
+
shaded += a3dPbrRectAreaLight(
|
|
1506
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
1507
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
1508
|
+
normal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
1509
|
+
materialBase, metallic, roughness, u_specularFactor, u_specularColorFactor
|
|
1510
|
+
);
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1513
|
+
vec3 lightDirection = -directionKind.xyz;
|
|
1514
|
+
float attenuation = 1.0;
|
|
1515
|
+
if (kind > 0.5) {
|
|
1516
|
+
vec3 toLight = positionRange.xyz - v_worldPosition;
|
|
1517
|
+
float distanceToLight = length(toLight);
|
|
1518
|
+
lightDirection = distanceToLight > 0.0001 ? toLight / distanceToLight : -directionKind.xyz;
|
|
1519
|
+
float range = max(positionRange.w, 0.0001);
|
|
1520
|
+
float rangeFalloff = clamp(1.0 - pow(distanceToLight / range, 4.0), 0.0, 1.0);
|
|
1521
|
+
rangeFalloff *= rangeFalloff;
|
|
1522
|
+
attenuation = rangeFalloff / max(distanceToLight * distanceToLight, 1.0);
|
|
1523
|
+
}
|
|
1524
|
+
if (kind > 1.5) {
|
|
1525
|
+
vec3 lightToFragment = normalize(v_worldPosition - positionRange.xyz);
|
|
1526
|
+
float cone = dot(normalize(directionKind.xyz), lightToFragment);
|
|
1527
|
+
float outer = cos(spotShadowLayer.x);
|
|
1528
|
+
float inner = cos(spotShadowLayer.x * max(1.0 - spotShadowLayer.y, 0.001));
|
|
1529
|
+
attenuation *= smoothstep(outer, inner, cone);
|
|
1530
|
+
}
|
|
1531
|
+
shaded += a3dPbrDirectLight(
|
|
1532
|
+
normal,
|
|
1533
|
+
viewDirection,
|
|
1534
|
+
lightDirection,
|
|
1535
|
+
colorIntensity.rgb,
|
|
1536
|
+
colorIntensity.a * attenuation * mix(1.0, kind > 0.5 && kind < 1.5 ? a3dPointShadowFactor(v_worldPosition, normal, lightDirection) : a3dForwardShadowFactor(v_worldPosition, normal, lightDirection), step(0.5, spotShadowLayer.z)),
|
|
1537
|
+
materialBase,
|
|
1538
|
+
metallic,
|
|
1539
|
+
roughness,
|
|
1540
|
+
u_specularFactor,
|
|
1541
|
+
u_specularColorFactor
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1544
|
+
if (baseColor.a < u_alphaCutoff) discard;
|
|
1545
|
+
vec3 fogged = a3dApplyEnvironmentFog(max(shaded, vec3(0.0)), v_worldPosition);
|
|
1546
|
+
outColor = vec4(a3dPbrEncodeOutput(fogged), baseColor.a);
|
|
1547
|
+
}
|
|
1548
|
+
`
|
|
1549
|
+
});
|
|
1550
|
+
library.register({
|
|
1551
|
+
name: DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_NAME,
|
|
1552
|
+
marker: DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_MARKER,
|
|
1553
|
+
vertex: `#version 300 es
|
|
1554
|
+
// ${DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_MARKER}
|
|
1555
|
+
precision highp float;
|
|
1556
|
+
#include <skinning_common>
|
|
1557
|
+
layout(location = 0) in vec3 a_position;
|
|
1558
|
+
layout(location = 5) in vec4 a_joints;
|
|
1559
|
+
layout(location = 6) in vec4 a_weights;
|
|
1560
|
+
layout(location = 8) in vec4 a_joints1;
|
|
1561
|
+
layout(location = 9) in vec4 a_weights1;
|
|
1562
|
+
uniform mat4 u_modelViewProjection;
|
|
1563
|
+
void main() {
|
|
1564
|
+
mat4 skin = a3dSkinMatrix8(a_joints, a_weights, a_joints1, a_weights1);
|
|
1565
|
+
float weightSum =
|
|
1566
|
+
a_weights.x + a_weights.y + a_weights.z + a_weights.w +
|
|
1567
|
+
a_weights1.x + a_weights1.y + a_weights1.z + a_weights1.w;
|
|
1568
|
+
vec4 skinnedPosition = weightSum > 0.0001 ? skin * vec4(a_position, 1.0) : vec4(a_position, 1.0);
|
|
1569
|
+
gl_Position = u_modelViewProjection * skinnedPosition;
|
|
1570
|
+
}
|
|
1571
|
+
`,
|
|
1572
|
+
fragment: `#version 300 es
|
|
1573
|
+
// ${DEFAULT_SKINNED_UNLIT_EIGHT_INFLUENCE_SHADER_MARKER}
|
|
1574
|
+
precision highp float;
|
|
1575
|
+
uniform vec4 u_baseColor;
|
|
1576
|
+
out vec4 outColor;
|
|
1577
|
+
void main() {
|
|
1578
|
+
outColor = u_baseColor;
|
|
1579
|
+
}
|
|
1580
|
+
`
|
|
1581
|
+
});
|
|
1582
|
+
library.register({
|
|
1583
|
+
name: DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_NAME,
|
|
1584
|
+
marker: DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_MARKER,
|
|
1585
|
+
vertex: `#version 300 es
|
|
1586
|
+
// ${DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_MARKER}
|
|
1587
|
+
precision highp float;
|
|
1588
|
+
#include <skinning_common>
|
|
1589
|
+
layout(location = 0) in vec3 a_position;
|
|
1590
|
+
layout(location = 1) in vec3 a_normal;
|
|
1591
|
+
layout(location = 2) in vec2 a_uv;
|
|
1592
|
+
layout(location = 3) in vec4 a_tangent;
|
|
1593
|
+
layout(location = 4) in vec4 a_color;
|
|
1594
|
+
layout(location = 5) in vec4 a_joints;
|
|
1595
|
+
layout(location = 6) in vec4 a_weights;
|
|
1596
|
+
layout(location = 8) in vec4 a_joints1;
|
|
1597
|
+
layout(location = 9) in vec4 a_weights1;
|
|
1598
|
+
uniform mat4 u_modelViewProjection;
|
|
1599
|
+
uniform mat4 u_modelMatrix;
|
|
1600
|
+
uniform mat4 u_normalMatrix;
|
|
1601
|
+
uniform vec2 u_baseColorTextureOffset;
|
|
1602
|
+
uniform vec2 u_baseColorTextureScale;
|
|
1603
|
+
uniform float u_baseColorTextureRotation;
|
|
1604
|
+
out vec3 v_normal;
|
|
1605
|
+
out vec4 v_tangent;
|
|
1606
|
+
out vec3 v_worldPosition;
|
|
1607
|
+
out vec2 v_uv;
|
|
1608
|
+
out vec4 v_vertexColor;
|
|
1609
|
+
out float v_weightSum;
|
|
1610
|
+
void main() {
|
|
1611
|
+
vec2 scaledUv = a_uv * u_baseColorTextureScale;
|
|
1612
|
+
float c = cos(u_baseColorTextureRotation);
|
|
1613
|
+
float s = sin(u_baseColorTextureRotation);
|
|
1614
|
+
v_uv = vec2(scaledUv.x * c - scaledUv.y * s, scaledUv.x * s + scaledUv.y * c) + u_baseColorTextureOffset;
|
|
1615
|
+
v_vertexColor = a_color;
|
|
1616
|
+
mat4 skin = a3dSkinMatrix8(a_joints, a_weights, a_joints1, a_weights1);
|
|
1617
|
+
v_weightSum =
|
|
1618
|
+
a_weights.x + a_weights.y + a_weights.z + a_weights.w +
|
|
1619
|
+
a_weights1.x + a_weights1.y + a_weights1.z + a_weights1.w;
|
|
1620
|
+
vec4 skinnedPosition = v_weightSum > 0.0001 ? skin * vec4(a_position, 1.0) : vec4(a_position, 1.0);
|
|
1621
|
+
// Normals and tangents use the same skin matrix with w = 0 so translation is
|
|
1622
|
+
// excluded; renormalizing happens in the fragment stage.
|
|
1623
|
+
vec3 skinnedNormal = (v_weightSum > 0.0001 ? skin * vec4(a_normal, 0.0) : vec4(a_normal, 0.0)).xyz;
|
|
1624
|
+
vec3 skinnedTangent = (v_weightSum > 0.0001 ? skin * vec4(a_tangent.xyz, 0.0) : vec4(a_tangent.xyz, 0.0)).xyz;
|
|
1625
|
+
v_normal = mat3(u_normalMatrix) * skinnedNormal;
|
|
1626
|
+
v_tangent = vec4(mat3(u_normalMatrix) * skinnedTangent, a_tangent.w);
|
|
1627
|
+
v_worldPosition = (u_modelMatrix * skinnedPosition).xyz;
|
|
1628
|
+
gl_Position = u_modelViewProjection * skinnedPosition;
|
|
1629
|
+
}
|
|
1630
|
+
`,
|
|
1631
|
+
fragment: `#version 300 es
|
|
1632
|
+
// ${DEFAULT_SKINNED_LIT_EIGHT_INFLUENCE_SHADER_MARKER}
|
|
1633
|
+
precision highp float;
|
|
1634
|
+
#include <lighting_common>
|
|
1635
|
+
#include <pbr_common>
|
|
1636
|
+
uniform vec4 u_baseColor;
|
|
1637
|
+
uniform sampler2D u_baseColorTexture;
|
|
1638
|
+
uniform float u_baseColorTextureEnabled;
|
|
1639
|
+
uniform sampler2D u_normalTexture;
|
|
1640
|
+
uniform float u_normalTextureEnabled;
|
|
1641
|
+
uniform float u_normalScale;
|
|
1642
|
+
uniform sampler2D u_metallicRoughnessTexture;
|
|
1643
|
+
uniform float u_metallicRoughnessTextureEnabled;
|
|
1644
|
+
uniform sampler2D u_occlusionTexture;
|
|
1645
|
+
uniform float u_occlusionTextureEnabled;
|
|
1646
|
+
uniform float u_occlusionStrength;
|
|
1647
|
+
uniform sampler2D u_emissiveTexture;
|
|
1648
|
+
uniform float u_emissiveTextureEnabled;
|
|
1649
|
+
uniform float u_alphaCutoff;
|
|
1650
|
+
uniform float u_metallic;
|
|
1651
|
+
uniform float u_roughness;
|
|
1652
|
+
uniform vec3 u_environmentColor;
|
|
1653
|
+
uniform float u_environmentIntensity;
|
|
1654
|
+
uniform vec3 u_environmentSkyColor;
|
|
1655
|
+
uniform vec3 u_environmentHorizonColor;
|
|
1656
|
+
uniform vec3 u_environmentGroundColor;
|
|
1657
|
+
uniform vec3 u_environmentSpecularColor;
|
|
1658
|
+
uniform float u_environmentMapIntensity;
|
|
1659
|
+
uniform float u_environmentSpecularIntensity;
|
|
1660
|
+
uniform sampler2D u_environmentMapTexture;
|
|
1661
|
+
uniform samplerCube u_environmentCubeMapTexture;
|
|
1662
|
+
uniform float u_environmentCubeMapTextureEnabled;
|
|
1663
|
+
uniform float u_environmentMapTextureEnabled;
|
|
1664
|
+
uniform float u_environmentMapTextureIntensity;
|
|
1665
|
+
uniform float u_environmentMapTextureSpecularIntensity;
|
|
1666
|
+
uniform float u_environmentMapTextureRotation;
|
|
1667
|
+
uniform float u_environmentMapTextureMipCount;
|
|
1668
|
+
uniform float u_environmentMapTextureEncoding;
|
|
1669
|
+
uniform sampler2D u_environmentBrdfLutTexture;
|
|
1670
|
+
uniform float u_environmentBrdfLutEnabled;
|
|
1671
|
+
uniform vec3 u_emissiveColor;
|
|
1672
|
+
uniform float u_emissiveStrength;
|
|
1673
|
+
uniform float u_clearcoatFactor;
|
|
1674
|
+
uniform float u_clearcoatRoughnessFactor;
|
|
1675
|
+
uniform float u_transmissionFactor;
|
|
1676
|
+
uniform float u_diffuseTransmissionFactor;
|
|
1677
|
+
uniform vec3 u_diffuseTransmissionColorFactor;
|
|
1678
|
+
uniform float u_transmissionFallbackEnergy;
|
|
1679
|
+
uniform float u_volumeThicknessFactor;
|
|
1680
|
+
uniform float u_volumeAttenuationDistance;
|
|
1681
|
+
uniform vec3 u_volumeAttenuationColor;
|
|
1682
|
+
uniform float u_transmissionParallaxStrength;
|
|
1683
|
+
uniform vec3 u_transmissionParallaxBoxMin;
|
|
1684
|
+
uniform vec3 u_transmissionParallaxBoxMax;
|
|
1685
|
+
uniform float u_transmissionBounceCount;
|
|
1686
|
+
uniform float u_transmissionCausticStrength;
|
|
1687
|
+
uniform float u_ior;
|
|
1688
|
+
uniform float u_specularFactor;
|
|
1689
|
+
uniform vec3 u_specularColorFactor;
|
|
1690
|
+
uniform vec3 u_sheenColorFactor;
|
|
1691
|
+
uniform float u_sheenRoughnessFactor;
|
|
1692
|
+
uniform float u_anisotropyStrength;
|
|
1693
|
+
uniform float u_anisotropyRotation;
|
|
1694
|
+
uniform float u_iridescenceFactor;
|
|
1695
|
+
uniform float u_iridescenceIor;
|
|
1696
|
+
uniform float u_iridescenceThicknessMinimum;
|
|
1697
|
+
uniform float u_iridescenceThicknessMaximum;
|
|
1698
|
+
uniform float u_dispersion;
|
|
1699
|
+
uniform float u_lightCount;
|
|
1700
|
+
uniform vec4 u_lightData[96];
|
|
1701
|
+
uniform float u_clusteredLightEnabled;
|
|
1702
|
+
uniform vec2 u_clusterGridSize;
|
|
1703
|
+
uniform vec2 u_clusterViewportSize;
|
|
1704
|
+
uniform sampler2D u_clusterLightData;
|
|
1705
|
+
uniform sampler2D u_clusterLightIndices;
|
|
1706
|
+
uniform sampler2D u_shadowMapTexture;
|
|
1707
|
+
uniform float u_shadowMapEnabled;
|
|
1708
|
+
uniform mat4 u_shadowMapMatrix;
|
|
1709
|
+
uniform float u_shadowMapStrength;
|
|
1710
|
+
uniform float u_shadowMapBias;
|
|
1711
|
+
uniform float u_shadowMapSlopeBias;
|
|
1712
|
+
uniform vec2 u_shadowMapTexelSize;
|
|
1713
|
+
uniform float u_shadowPcfSampleCount;
|
|
1714
|
+
uniform vec4 u_shadowPcfSamples[32];
|
|
1715
|
+
uniform sampler2D u_pointShadowMapTexture;
|
|
1716
|
+
uniform float u_pointShadowMapEnabled;
|
|
1717
|
+
uniform vec3 u_pointShadowLightPosition;
|
|
1718
|
+
uniform float u_pointShadowRange;
|
|
1719
|
+
uniform mat4 u_pointShadowFaceMatrices[6];
|
|
1720
|
+
uniform vec4 u_pointShadowFaceRects[6];
|
|
1721
|
+
uniform float u_pointShadowStrength;
|
|
1722
|
+
uniform float u_pointShadowBias;
|
|
1723
|
+
uniform float u_pointShadowSlopeBias;
|
|
1724
|
+
uniform vec2 u_pointShadowTexelSize;
|
|
1725
|
+
uniform float u_pointShadowPcfSampleCount;
|
|
1726
|
+
uniform vec4 u_pointShadowPcfSamples[32];
|
|
1727
|
+
uniform float u_outputColorSpace;
|
|
1728
|
+
uniform vec3 u_cameraPosition;
|
|
1729
|
+
uniform float u_environmentFogEnabled;
|
|
1730
|
+
uniform float u_environmentFogMode;
|
|
1731
|
+
uniform vec3 u_environmentFogColor;
|
|
1732
|
+
uniform float u_environmentFogNear;
|
|
1733
|
+
uniform float u_environmentFogFar;
|
|
1734
|
+
uniform float u_environmentFogDensity;
|
|
1735
|
+
uniform float u_environmentFogHeightFalloff;
|
|
1736
|
+
uniform float u_environmentFogHeightReference;
|
|
1737
|
+
uniform float u_environmentFogMaxOpacity;
|
|
1738
|
+
in vec3 v_normal;
|
|
1739
|
+
in vec4 v_tangent;
|
|
1740
|
+
in vec3 v_worldPosition;
|
|
1741
|
+
in vec2 v_uv;
|
|
1742
|
+
in vec4 v_vertexColor;
|
|
1743
|
+
in float v_weightSum;
|
|
1744
|
+
out vec4 outColor;
|
|
1745
|
+
#include <environment_fog_common>
|
|
1746
|
+
vec2 a3dEnvironmentEquirectUv(vec3 direction, float rotation) {
|
|
1747
|
+
vec3 d = normalize(direction);
|
|
1748
|
+
float u = atan(d.z, d.x) / 6.28318530718 + 0.5 + rotation;
|
|
1749
|
+
float v = acos(clamp(d.y, -1.0, 1.0)) / 3.14159265359;
|
|
1750
|
+
return vec2(fract(u), clamp(v, 0.0, 1.0));
|
|
1751
|
+
}
|
|
1752
|
+
vec3 a3dEnvironmentCubeDirection(vec3 direction, float rotation) {
|
|
1753
|
+
float angle = rotation * 6.28318530718;
|
|
1754
|
+
float c = cos(angle);
|
|
1755
|
+
float s = sin(angle);
|
|
1756
|
+
vec3 d = normalize(direction);
|
|
1757
|
+
return normalize(vec3(c * d.x - s * d.z, d.y, s * d.x + c * d.z));
|
|
1758
|
+
}
|
|
1759
|
+
vec3 a3dPbrDecodeEnvironmentSrgb(vec3 encodedColor) {
|
|
1760
|
+
return max(encodedColor, vec3(0.0));
|
|
1761
|
+
}
|
|
1762
|
+
vec3 a3dPbrDecodeEnvironmentRgbe(vec4 encodedSample) {
|
|
1763
|
+
float exponent = encodedSample.a * 255.0;
|
|
1764
|
+
float scale = exponent <= 0.0 ? 0.0 : exp2(exponent - 128.0) * (255.0 / 256.0);
|
|
1765
|
+
return max(encodedSample.rgb * scale, vec3(0.0));
|
|
1766
|
+
}
|
|
1767
|
+
vec3 a3dPbrDecodeEnvironmentSample(vec4 encodedSample) {
|
|
1768
|
+
if (u_environmentMapTextureEncoding > 1.5) return max(encodedSample.rgb, vec3(0.0));
|
|
1769
|
+
if (u_environmentMapTextureEncoding > 0.5) return a3dPbrDecodeEnvironmentRgbe(encodedSample);
|
|
1770
|
+
return a3dPbrDecodeEnvironmentSrgb(encodedSample.rgb);
|
|
1771
|
+
}
|
|
1772
|
+
vec3 a3dPbrBoundHdrSpecularRadiance(vec3 radiance) {
|
|
1773
|
+
vec3 nonNegative = max(radiance, vec3(0.0));
|
|
1774
|
+
vec3 softKnee = nonNegative / (vec3(1.0) + max(nonNegative - vec3(1.0), vec3(0.0)) * 0.58);
|
|
1775
|
+
float maxChannel = max(max(softKnee.r, softKnee.g), softKnee.b);
|
|
1776
|
+
return maxChannel > 1.65 ? softKnee * (1.65 / maxChannel) : softKnee;
|
|
1777
|
+
}
|
|
1778
|
+
vec3 a3dPbrClampSampledSpecularEdgeEnergy(vec3 radiance, float nDotV, float roughness) {
|
|
1779
|
+
float faceOn = smoothstep(0.12, 0.55, clamp(nDotV, 0.0, 1.0));
|
|
1780
|
+
float roughEnergy = mix(0.6, 1.0, clamp(roughness, 0.0, 1.0));
|
|
1781
|
+
float edgeCap = mix(0.12, 1.2, faceOn) * roughEnergy;
|
|
1782
|
+
float edgeScale = mix(0.14, 0.92, faceOn);
|
|
1783
|
+
vec3 bounded = min(radiance * edgeScale, vec3(edgeCap));
|
|
1784
|
+
return max(bounded, vec3(0.0));
|
|
1785
|
+
}
|
|
1786
|
+
vec4 a3dPbrEnvironmentSampleRaw(vec3 direction, float lod) {
|
|
1787
|
+
vec4 equirectSample = textureLod(u_environmentMapTexture, a3dEnvironmentEquirectUv(direction, u_environmentMapTextureRotation), lod);
|
|
1788
|
+
vec4 cubeSample = textureLod(u_environmentCubeMapTexture, a3dEnvironmentCubeDirection(direction, u_environmentMapTextureRotation), lod);
|
|
1789
|
+
return mix(equirectSample, cubeSample, step(0.5, u_environmentCubeMapTextureEnabled));
|
|
1790
|
+
}
|
|
1791
|
+
vec3 a3dSkinnedPbrNormal(vec3 baseNormal, vec4 tangentFrame, vec2 uv) {
|
|
1792
|
+
vec3 sampled = texture(u_normalTexture, uv).xyz * 2.0 - 1.0;
|
|
1793
|
+
vec3 n = normalize(baseNormal);
|
|
1794
|
+
vec3 tangent = normalize(tangentFrame.xyz);
|
|
1795
|
+
vec3 bitangent = normalize(cross(n, tangent) * tangentFrame.w);
|
|
1796
|
+
return normalize(tangent * sampled.x * u_normalScale + bitangent * sampled.y * u_normalScale + n * max(sampled.z, 0.001));
|
|
1797
|
+
}
|
|
1798
|
+
float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
1799
|
+
if (u_shadowMapEnabled < 0.5) return 1.0;
|
|
1800
|
+
vec4 lightPosition = u_shadowMapMatrix * vec4(worldPosition, 1.0);
|
|
1801
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
1802
|
+
vec2 uv = projected.xy * 0.5 + 0.5;
|
|
1803
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 1.0;
|
|
1804
|
+
vec3 receiverNormal = normalize(normal);
|
|
1805
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1806
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1807
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
1808
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
1809
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
1810
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
1811
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
1812
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
1813
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
1814
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
1815
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
1816
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
1817
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
1818
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1819
|
+
float shadowed = 0.0;
|
|
1820
|
+
float totalWeight = 0.0;
|
|
1821
|
+
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
1822
|
+
for (int i = 0; i < 32; ++i) {
|
|
1823
|
+
if (i >= sampleCount) break;
|
|
1824
|
+
vec4 sampleData = u_shadowPcfSamples[i];
|
|
1825
|
+
float weight = max(sampleData.z, 0.0);
|
|
1826
|
+
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
1827
|
+
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
1828
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
1829
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
1830
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1831
|
+
totalWeight += weight;
|
|
1832
|
+
}
|
|
1833
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
1834
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_shadowMapStrength, 0.0, 1.0));
|
|
1835
|
+
}
|
|
1836
|
+
float a3dPointShadowFaceIndex(vec3 direction) {
|
|
1837
|
+
vec3 absoluteDirection = abs(direction);
|
|
1838
|
+
if (absoluteDirection.x >= absoluteDirection.y && absoluteDirection.x >= absoluteDirection.z) return direction.x >= 0.0 ? 0.0 : 1.0;
|
|
1839
|
+
if (absoluteDirection.y >= absoluteDirection.x && absoluteDirection.y >= absoluteDirection.z) return direction.y >= 0.0 ? 2.0 : 3.0;
|
|
1840
|
+
return direction.z >= 0.0 ? 4.0 : 5.0;
|
|
1841
|
+
}
|
|
1842
|
+
float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection) {
|
|
1843
|
+
if (u_pointShadowMapEnabled < 0.5) return 1.0;
|
|
1844
|
+
vec3 lightToFragment = worldPosition - u_pointShadowLightPosition;
|
|
1845
|
+
float distanceToLight = length(lightToFragment);
|
|
1846
|
+
if (distanceToLight > u_pointShadowRange) return 1.0;
|
|
1847
|
+
int faceIndex = int(a3dPointShadowFaceIndex(lightToFragment));
|
|
1848
|
+
vec4 lightPosition = u_pointShadowFaceMatrices[faceIndex] * vec4(worldPosition, 1.0);
|
|
1849
|
+
vec3 projected = lightPosition.xyz / max(lightPosition.w, 0.0001);
|
|
1850
|
+
vec2 localUv = projected.xy * 0.5 + 0.5;
|
|
1851
|
+
if (localUv.x < 0.0 || localUv.x > 1.0 || localUv.y < 0.0 || localUv.y > 1.0) return 1.0;
|
|
1852
|
+
vec4 rect = u_pointShadowFaceRects[faceIndex];
|
|
1853
|
+
vec2 uv = rect.xy + localUv * rect.zw;
|
|
1854
|
+
vec3 receiverNormal = normalize(normal);
|
|
1855
|
+
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1856
|
+
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1857
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
1858
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
1859
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
1860
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
1861
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
1862
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
1863
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
1864
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
1865
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
1866
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
1867
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
1868
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1869
|
+
float shadowed = 0.0;
|
|
1870
|
+
float totalWeight = 0.0;
|
|
1871
|
+
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
1872
|
+
for (int i = 0; i < 32; ++i) {
|
|
1873
|
+
if (i >= sampleCount) break;
|
|
1874
|
+
vec4 sampleData = u_pointShadowPcfSamples[i];
|
|
1875
|
+
float weight = max(sampleData.z, 0.0);
|
|
1876
|
+
vec2 offset = sampleData.xy * u_pointShadowTexelSize;
|
|
1877
|
+
float storedDepth = texture(u_pointShadowMapTexture, uv + offset).r;
|
|
1878
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
1879
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
1880
|
+
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1881
|
+
totalWeight += weight;
|
|
1882
|
+
}
|
|
1883
|
+
float occlusion = totalWeight > 0.0 ? shadowed / totalWeight : 0.0;
|
|
1884
|
+
return mix(1.0, 1.0 - occlusion, clamp(u_pointShadowStrength, 0.0, 1.0));
|
|
1885
|
+
}
|
|
1886
|
+
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
1887
|
+
vec3 color = max(linearColor, vec3(0.0));
|
|
1888
|
+
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
1889
|
+
vec3 srgb = pow(filmic, vec3(1.0 / 2.2));
|
|
1890
|
+
return mix(color, srgb, step(0.5, u_outputColorSpace));
|
|
1891
|
+
}
|
|
1892
|
+
void main() {
|
|
1893
|
+
vec3 normal = normalize(v_normal);
|
|
1894
|
+
normal = mix(normal, a3dSkinnedPbrNormal(v_normal, v_tangent, v_uv), step(0.5, u_normalTextureEnabled));
|
|
1895
|
+
if (!gl_FrontFacing) normal = -normal;
|
|
1896
|
+
vec3 viewDirection = normalize(u_cameraPosition - v_worldPosition);
|
|
1897
|
+
vec4 sampledBaseColor = texture(u_baseColorTexture, v_uv);
|
|
1898
|
+
vec4 decodedBaseColor = vec4(a3dPbrDecodeEnvironmentSrgb(sampledBaseColor.rgb), sampledBaseColor.a);
|
|
1899
|
+
float baseColorTextureWeight = clamp(u_baseColorTextureEnabled, 0.0, 1.0);
|
|
1900
|
+
vec4 baseColor = mix(u_baseColor, u_baseColor * decodedBaseColor, baseColorTextureWeight) * v_vertexColor;
|
|
1901
|
+
vec4 metallicRoughnessSample = texture(u_metallicRoughnessTexture, v_uv);
|
|
1902
|
+
float metallic = mix(u_metallic, clamp(u_metallic * metallicRoughnessSample.b, 0.0, 1.0), step(0.5, u_metallicRoughnessTextureEnabled));
|
|
1903
|
+
float roughness = mix(u_roughness, clamp(u_roughness * metallicRoughnessSample.g, 0.0, 1.0), step(0.5, u_metallicRoughnessTextureEnabled));
|
|
1904
|
+
float occlusion = mix(1.0, mix(1.0, texture(u_occlusionTexture, v_uv).r, clamp(u_occlusionStrength, 0.0, 1.0)), step(0.5, u_occlusionTextureEnabled));
|
|
1905
|
+
vec3 emissive = u_emissiveColor * u_emissiveStrength * mix(vec3(1.0), a3dPbrDecodeEnvironmentSrgb(texture(u_emissiveTexture, v_uv).rgb), step(0.5, u_emissiveTextureEnabled));
|
|
1906
|
+
vec3 materialBase = a3dApplyAdvancedPbrLobes(
|
|
1907
|
+
baseColor.rgb,
|
|
1908
|
+
u_clearcoatFactor,
|
|
1909
|
+
u_clearcoatRoughnessFactor,
|
|
1910
|
+
u_transmissionFactor,
|
|
1911
|
+
u_diffuseTransmissionFactor,
|
|
1912
|
+
u_diffuseTransmissionColorFactor,
|
|
1913
|
+
u_transmissionFallbackEnergy,
|
|
1914
|
+
u_volumeThicknessFactor,
|
|
1915
|
+
u_volumeAttenuationDistance,
|
|
1916
|
+
u_volumeAttenuationColor,
|
|
1917
|
+
u_ior,
|
|
1918
|
+
u_specularFactor,
|
|
1919
|
+
u_specularColorFactor,
|
|
1920
|
+
u_sheenColorFactor,
|
|
1921
|
+
u_sheenRoughnessFactor,
|
|
1922
|
+
u_anisotropyStrength,
|
|
1923
|
+
u_anisotropyRotation,
|
|
1924
|
+
u_iridescenceFactor,
|
|
1925
|
+
u_iridescenceIor,
|
|
1926
|
+
u_iridescenceThicknessMinimum,
|
|
1927
|
+
u_iridescenceThicknessMaximum,
|
|
1928
|
+
u_dispersion
|
|
1929
|
+
);
|
|
1930
|
+
float environmentHemi = mix(0.35, 1.0, clamp(normal.y * 0.5 + 0.5, 0.0, 1.0));
|
|
1931
|
+
vec3 ambientEnvironment = u_environmentColor * u_environmentIntensity * environmentHemi;
|
|
1932
|
+
float proceduralEnvironmentWeight = step(0.0001, u_environmentMapIntensity);
|
|
1933
|
+
float skyBlend = clamp(normal.y * 0.5 + 0.5, 0.0, 1.0);
|
|
1934
|
+
float horizonBlend = 1.0 - abs(normal.y);
|
|
1935
|
+
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
1936
|
+
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
1937
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
1938
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
1939
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
1940
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
1941
|
+
// separate physical contributions, so they sum.
|
|
1942
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
1943
|
+
vec3 reflectionDirection = reflect(-viewDirection, normal);
|
|
1944
|
+
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
1945
|
+
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
1946
|
+
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
1947
|
+
float clampedRoughness = clamp(roughness, 0.0, 1.0);
|
|
1948
|
+
float reflectionBand = pow(clamp(reflectionDirection.y * 0.5 + 0.5, 0.0, 1.0), mix(18.0, 2.0, clampedRoughness));
|
|
1949
|
+
float roughEnvironmentFloor = mix(0.04, 0.38, clampedRoughness);
|
|
1950
|
+
float proceduralSpecularResponse = max(reflectionBand, roughEnvironmentFloor);
|
|
1951
|
+
float horizonStripe = pow(clamp(1.0 - abs(reflectionDirection.y), 0.0, 1.0), mix(14.0, 3.0, clampedRoughness));
|
|
1952
|
+
float sideStripe = pow(clamp(abs(reflectionDirection.x), 0.0, 1.0), mix(10.0, 3.0, clampedRoughness)) * smoothstep(0.0, 0.72, 1.0 - abs(reflectionDirection.y));
|
|
1953
|
+
float overheadStripe = pow(clamp(reflectionDirection.y * 0.5 + 0.5, 0.0, 1.0), mix(22.0, 4.0, clampedRoughness));
|
|
1954
|
+
vec3 proceduralSpecularColor = u_environmentSpecularColor * proceduralSpecularResponse
|
|
1955
|
+
+ u_environmentHorizonColor * horizonStripe * 0.42
|
|
1956
|
+
+ u_environmentSkyColor * overheadStripe * 0.28
|
|
1957
|
+
+ u_environmentGroundColor * sideStripe * 0.22;
|
|
1958
|
+
vec3 proceduralSpecular = proceduralSpecularColor * u_environmentSpecularIntensity * proceduralEnvironmentWeight;
|
|
1959
|
+
float environmentLod = clampedRoughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
1960
|
+
vec3 sampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
1961
|
+
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
1962
|
+
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clampedRoughness)).rg;
|
|
1963
|
+
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
1964
|
+
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(1.1, 0.85, roughness);
|
|
1965
|
+
vec3 shaded = a3dPbrEnvironmentLightSplitSum(
|
|
1966
|
+
normal,
|
|
1967
|
+
viewDirection,
|
|
1968
|
+
mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight),
|
|
1969
|
+
proceduralSpecular + sampledSpecular,
|
|
1970
|
+
mix(vec2(1.0, 0.0), brdfLut, step(0.0001, u_environmentBrdfLutEnabled)),
|
|
1971
|
+
materialBase,
|
|
1972
|
+
metallic,
|
|
1973
|
+
roughness,
|
|
1974
|
+
u_specularFactor,
|
|
1975
|
+
u_specularColorFactor
|
|
1976
|
+
) * occlusion + emissive;
|
|
1977
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
1978
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
1979
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
1980
|
+
for (int i = 0; i < 64; ++i) {
|
|
1981
|
+
if (i >= count) break;
|
|
1982
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
1983
|
+
int baseIndex = lightIndex * 6;
|
|
1984
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
1985
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
1986
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
1987
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
1988
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
1989
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
1990
|
+
float kind = directionKind.w;
|
|
1991
|
+
if (kind > 2.5) {
|
|
1992
|
+
shaded += a3dPbrRectAreaLight(
|
|
1993
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
1994
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
1995
|
+
normal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
1996
|
+
materialBase, metallic, roughness, u_specularFactor, u_specularColorFactor
|
|
1997
|
+
);
|
|
1998
|
+
continue;
|
|
1999
|
+
}
|
|
1369
2000
|
vec3 lightDirection = -directionKind.xyz;
|
|
1370
2001
|
float attenuation = 1.0;
|
|
1371
2002
|
if (kind > 0.5) {
|
|
@@ -1539,7 +2170,12 @@ uniform vec3 u_specularColorFactor;
|
|
|
1539
2170
|
uniform vec3 u_sheenColorFactor;
|
|
1540
2171
|
uniform float u_sheenRoughnessFactor;
|
|
1541
2172
|
uniform float u_lightCount;
|
|
1542
|
-
uniform vec4 u_lightData[
|
|
2173
|
+
uniform vec4 u_lightData[96];
|
|
2174
|
+
uniform float u_clusteredLightEnabled;
|
|
2175
|
+
uniform vec2 u_clusterGridSize;
|
|
2176
|
+
uniform vec2 u_clusterViewportSize;
|
|
2177
|
+
uniform sampler2D u_clusterLightData;
|
|
2178
|
+
uniform sampler2D u_clusterLightIndices;
|
|
1543
2179
|
uniform sampler2D u_normalTexture;
|
|
1544
2180
|
uniform float u_normalScale;
|
|
1545
2181
|
uniform sampler2D u_shadowMapTexture;
|
|
@@ -1597,8 +2233,18 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
1597
2233
|
vec3 receiverNormal = normalize(normal);
|
|
1598
2234
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
1599
2235
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
1600
|
-
|
|
1601
|
-
|
|
2236
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
2237
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
2238
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
2239
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
2240
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
2241
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
2242
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
2243
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
2244
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
2245
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
2246
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
2247
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1602
2248
|
float shadowed = 0.0;
|
|
1603
2249
|
float totalWeight = 0.0;
|
|
1604
2250
|
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
@@ -1608,6 +2254,8 @@ float a3dForwardShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirectio
|
|
|
1608
2254
|
float weight = max(sampleData.z, 0.0);
|
|
1609
2255
|
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
1610
2256
|
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
2257
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
2258
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
1611
2259
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
1612
2260
|
totalWeight += weight;
|
|
1613
2261
|
}
|
|
@@ -1626,7 +2274,12 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
1626
2274
|
vec4 rect = u_pointShadowFaceRects[faceIndex];
|
|
1627
2275
|
vec2 uv = rect.xy + localUv * rect.zw;
|
|
1628
2276
|
float normalDotLight = clamp(abs(dot(normalize(normal), normalize(lightDirection))), 0.0, 1.0);
|
|
1629
|
-
|
|
2277
|
+
// Same per-sample, tangent-scaled slope bias as the directional and atlas paths. These
|
|
2278
|
+
// cubemap-face variants inline the sample fetch, but they share the identical acne
|
|
2279
|
+
// mechanism: a centre-only, (1 - N.L)-scaled bias under-compensates every outer tap.
|
|
2280
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
2281
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
2282
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
1630
2283
|
float shadowed = 0.0;
|
|
1631
2284
|
float totalWeight = 0.0;
|
|
1632
2285
|
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
@@ -1634,6 +2287,8 @@ float a3dPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDirection)
|
|
|
1634
2287
|
if (i >= sampleCount) break;
|
|
1635
2288
|
vec4 sampleData = u_pointShadowPcfSamples[i];
|
|
1636
2289
|
float weight = max(sampleData.z, 0.0);
|
|
2290
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
2291
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
1637
2292
|
shadowed += (receiverDepth > texture(u_pointShadowMapTexture, uv + sampleData.xy * u_pointShadowTexelSize).r ? 1.0 : 0.0) * weight;
|
|
1638
2293
|
totalWeight += weight;
|
|
1639
2294
|
}
|
|
@@ -1693,11 +2348,16 @@ vec3 a3dPbrEnvironmentDiffuseInput(vec3 normal) {
|
|
|
1693
2348
|
float horizonBlend = 1.0 - abs(normal.y);
|
|
1694
2349
|
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
1695
2350
|
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
1696
|
-
|
|
2351
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
2352
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
2353
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
2354
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
2355
|
+
// separate physical contributions, so they sum.
|
|
2356
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
1697
2357
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
1698
2358
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
1699
2359
|
vec3 sampledDiffuse = a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
1700
|
-
return mix(environmentDiffuse,
|
|
2360
|
+
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
1701
2361
|
}
|
|
1702
2362
|
vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
1703
2363
|
float proceduralEnvironmentWeight = step(0.0001, u_environmentMapIntensity);
|
|
@@ -1711,11 +2371,15 @@ vec3 a3dPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float rough
|
|
|
1711
2371
|
float environmentLod = clampedRoughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
1712
2372
|
vec3 sampledSpecular = a3dPbrBoundHdrSpecularRadiance(a3dPbrDecodeEnvironmentSample(a3dPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
1713
2373
|
float nDotV = clamp(dot(normal, viewDirection), 0.0, 1.0);
|
|
1714
|
-
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clampedRoughness)).rg;
|
|
1715
2374
|
sampledSpecular = a3dPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
1716
2375
|
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
1717
2376
|
return proceduralSpecular + sampledSpecular;
|
|
1718
2377
|
}
|
|
2378
|
+
vec2 a3dPbrEnvironmentBrdfInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
2379
|
+
float nDotV = clamp(dot(normalize(normal), normalize(viewDirection)), 0.0, 1.0);
|
|
2380
|
+
vec2 lut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clamp(roughness, 0.0, 1.0))).rg;
|
|
2381
|
+
return mix(vec2(1.0, 0.0), lut, step(0.0001, u_environmentBrdfLutEnabled));
|
|
2382
|
+
}
|
|
1719
2383
|
vec3 a3dPbrEncodeOutput(vec3 linearColor) {
|
|
1720
2384
|
vec3 color = max(linearColor, vec3(0.0));
|
|
1721
2385
|
vec3 filmic = clamp((color * (2.51 * color + 0.03)) / (color * (2.43 * color + 0.59) + 0.14), vec3(0.0), vec3(1.0));
|
|
@@ -1727,25 +2391,41 @@ void main() {
|
|
|
1727
2391
|
if (!gl_FrontFacing) mappedNormal = -mappedNormal;
|
|
1728
2392
|
vec3 viewDirection = normalize(u_cameraPosition - v_worldPosition);
|
|
1729
2393
|
vec3 materialBase = u_baseColor.rgb * v_vertexColor.rgb;
|
|
1730
|
-
vec3 shaded = u_emissiveColor * u_emissiveStrength +
|
|
2394
|
+
vec3 shaded = u_emissiveColor * u_emissiveStrength + a3dPbrEnvironmentLightSplitSum(
|
|
1731
2395
|
mappedNormal,
|
|
1732
2396
|
viewDirection,
|
|
1733
2397
|
a3dPbrEnvironmentDiffuseInput(mappedNormal),
|
|
1734
2398
|
a3dPbrEnvironmentSpecularInput(mappedNormal, viewDirection, u_roughness),
|
|
2399
|
+
a3dPbrEnvironmentBrdfInput(mappedNormal, viewDirection, u_roughness),
|
|
1735
2400
|
materialBase,
|
|
1736
2401
|
u_metallic,
|
|
1737
2402
|
u_roughness,
|
|
1738
2403
|
u_specularFactor,
|
|
1739
2404
|
u_specularColorFactor
|
|
1740
2405
|
);
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
2406
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
2407
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
2408
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
2409
|
+
for (int i = 0; i < 64; ++i) {
|
|
2410
|
+
if (i >= count) break;
|
|
2411
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
2412
|
+
int baseIndex = lightIndex * 6;
|
|
2413
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
2414
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
2415
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
2416
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
2417
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
2418
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
1748
2419
|
float kind = directionKind.w;
|
|
2420
|
+
if (kind > 2.5) {
|
|
2421
|
+
shaded += a3dPbrRectAreaLight(
|
|
2422
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
2423
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
2424
|
+
mappedNormal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
2425
|
+
materialBase, u_metallic, u_roughness, u_specularFactor, u_specularColorFactor
|
|
2426
|
+
);
|
|
2427
|
+
continue;
|
|
2428
|
+
}
|
|
1749
2429
|
vec3 lightDirection = -directionKind.xyz;
|
|
1750
2430
|
float attenuation = 1.0;
|
|
1751
2431
|
if (kind > 0.5) {
|
|
@@ -1778,13 +2458,13 @@ void main() {
|
|
|
1778
2458
|
name: DEFAULT_TEXTURED_PBR_SHADER_NAME,
|
|
1779
2459
|
marker: DEFAULT_TEXTURED_PBR_SHADER_MARKER,
|
|
1780
2460
|
variants: [
|
|
1781
|
-
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } },
|
|
1782
|
-
{ name: DEFAULT_TEXTURED_PBR_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } },
|
|
1783
|
-
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } },
|
|
1784
|
-
{ name: DEFAULT_TEXTURED_PBR_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } },
|
|
1785
|
-
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } },
|
|
1786
|
-
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_SPECULAR_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } },
|
|
1787
|
-
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true } }
|
|
2461
|
+
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2462
|
+
{ name: DEFAULT_TEXTURED_PBR_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2463
|
+
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2464
|
+
{ name: DEFAULT_TEXTURED_PBR_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2465
|
+
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_TRANSMISSION_VOLUME_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_TRANSMISSION_VOLUME_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2466
|
+
{ name: DEFAULT_TEXTURED_PBR_CLEARCOAT_SPECULAR_TEXTURES_VARIANT, defines: { A3D_PBR_CLEARCOAT_TEXTURES: true, A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } },
|
|
2467
|
+
{ name: DEFAULT_TEXTURED_PBR_SPECULAR_SHEEN_ANISOTROPY_IRIDESCENCE_TEXTURES_VARIANT, defines: { A3D_PBR_SPECULAR_TEXTURES: true, A3D_PBR_SPECULAR_SHEEN_ANISOTROPY_TEXTURES: true, A3D_PBR_IRIDESCENCE_TEXTURES: true, A3D_PBR_DISABLE_TRANSMISSION_BACKDROP: true, A3D_PBR_DISABLE_CLUSTERED_LIGHTING: true } }
|
|
1788
2468
|
],
|
|
1789
2469
|
vertex: `#version 300 es
|
|
1790
2470
|
// ${DEFAULT_TEXTURED_PBR_SHADER_MARKER}
|
|
@@ -1880,7 +2560,14 @@ uniform float u_iridescenceThicknessMinimum;
|
|
|
1880
2560
|
uniform float u_iridescenceThicknessMaximum;
|
|
1881
2561
|
uniform float u_dispersion;
|
|
1882
2562
|
uniform float u_lightCount;
|
|
1883
|
-
uniform vec4 u_lightData[
|
|
2563
|
+
uniform vec4 u_lightData[96];
|
|
2564
|
+
#ifndef A3D_PBR_DISABLE_CLUSTERED_LIGHTING
|
|
2565
|
+
uniform float u_clusteredLightEnabled;
|
|
2566
|
+
uniform vec2 u_clusterGridSize;
|
|
2567
|
+
uniform vec2 u_clusterViewportSize;
|
|
2568
|
+
uniform sampler2D u_clusterLightData;
|
|
2569
|
+
uniform sampler2D u_clusterLightIndices;
|
|
2570
|
+
#endif
|
|
1884
2571
|
uniform sampler2D u_shadowMapTexture;
|
|
1885
2572
|
uniform float u_shadowMapEnabled;
|
|
1886
2573
|
uniform mat4 u_shadowMapMatrix;
|
|
@@ -2147,8 +2834,18 @@ float a3dTexturedPbrShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDire
|
|
|
2147
2834
|
vec3 receiverNormal = normalize(normal);
|
|
2148
2835
|
vec3 receiverLightDirection = lightDirection / max(length(lightDirection), 0.0001);
|
|
2149
2836
|
float normalDotLight = clamp(abs(dot(receiverNormal, receiverLightDirection)), 0.0, 1.0);
|
|
2150
|
-
|
|
2151
|
-
|
|
2837
|
+
// Slope-scaled depth bias must be evaluated per PCF sample, not once for the kernel
|
|
2838
|
+
// centre. A sample offset N texels away on a receiver sloped relative to the light sees a
|
|
2839
|
+
// depth difference proportional to N, so a centre-only bias under-compensates every outer
|
|
2840
|
+
// tap and the receiver shadows itself. Scaling by each sample's own texel distance keeps
|
|
2841
|
+
// wide kernels acne-free without inflating the constant bias into peter-panning.
|
|
2842
|
+
// The depth gradient across one shadow texel is tan(angle between receiver normal and
|
|
2843
|
+
// light), not (1 - N.L). The linear form collapses toward zero far faster than the real
|
|
2844
|
+
// gradient grows, so it under-biases exactly the grazing angles that need the most
|
|
2845
|
+
// compensation. Clamped so a near-perpendicular receiver cannot demand unbounded bias.
|
|
2846
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
2847
|
+
float slopeTexelBias = slopeTangent * u_shadowMapSlopeBias * max(u_shadowMapTexelSize.x, u_shadowMapTexelSize.y);
|
|
2848
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
2152
2849
|
float shadowed = 0.0;
|
|
2153
2850
|
float totalWeight = 0.0;
|
|
2154
2851
|
int sampleCount = clamp(int(u_shadowPcfSampleCount), 1, 32);
|
|
@@ -2158,6 +2855,8 @@ float a3dTexturedPbrShadowFactor(vec3 worldPosition, vec3 normal, vec3 lightDire
|
|
|
2158
2855
|
float weight = max(sampleData.z, 0.0);
|
|
2159
2856
|
vec2 offset = sampleData.xy * u_shadowMapTexelSize;
|
|
2160
2857
|
float storedDepth = texture(u_shadowMapTexture, uv + offset).r;
|
|
2858
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
2859
|
+
float receiverDepth = projectedDepth - u_shadowMapBias - slopeTexelBias * sampleTexelDistance;
|
|
2161
2860
|
shadowed += (receiverDepth > storedDepth ? 1.0 : 0.0) * weight;
|
|
2162
2861
|
totalWeight += weight;
|
|
2163
2862
|
}
|
|
@@ -2176,7 +2875,12 @@ float a3dTexturedPbrPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 ligh
|
|
|
2176
2875
|
vec4 rect = u_pointShadowFaceRects[faceIndex];
|
|
2177
2876
|
vec2 uv = rect.xy + localUv * rect.zw;
|
|
2178
2877
|
float normalDotLight = clamp(abs(dot(normalize(normal), normalize(lightDirection))), 0.0, 1.0);
|
|
2179
|
-
|
|
2878
|
+
// Same per-sample, tangent-scaled slope bias as the directional and atlas paths. These
|
|
2879
|
+
// cubemap-face variants inline the sample fetch, but they share the identical acne
|
|
2880
|
+
// mechanism: a centre-only, (1 - N.L)-scaled bias under-compensates every outer tap.
|
|
2881
|
+
float slopeTangent = min(sqrt(max(1.0 - normalDotLight * normalDotLight, 0.0)) / max(normalDotLight, 0.05), 8.0);
|
|
2882
|
+
float slopeTexelBias = slopeTangent * u_pointShadowSlopeBias * max(u_pointShadowTexelSize.x, u_pointShadowTexelSize.y);
|
|
2883
|
+
float projectedDepth = projected.z * 0.5 + 0.5;
|
|
2180
2884
|
float shadowed = 0.0;
|
|
2181
2885
|
float totalWeight = 0.0;
|
|
2182
2886
|
int sampleCount = clamp(int(u_pointShadowPcfSampleCount), 1, 32);
|
|
@@ -2184,6 +2888,8 @@ float a3dTexturedPbrPointShadowFactor(vec3 worldPosition, vec3 normal, vec3 ligh
|
|
|
2184
2888
|
if (i >= sampleCount) break;
|
|
2185
2889
|
vec4 sampleData = u_pointShadowPcfSamples[i];
|
|
2186
2890
|
float weight = max(sampleData.z, 0.0);
|
|
2891
|
+
float sampleTexelDistance = max(1.0, length(sampleData.xy));
|
|
2892
|
+
float receiverDepth = projectedDepth - u_pointShadowBias - slopeTexelBias * sampleTexelDistance;
|
|
2187
2893
|
shadowed += (receiverDepth > texture(u_pointShadowMapTexture, uv + sampleData.xy * u_pointShadowTexelSize).r ? 1.0 : 0.0) * weight;
|
|
2188
2894
|
totalWeight += weight;
|
|
2189
2895
|
}
|
|
@@ -2229,11 +2935,16 @@ vec3 a3dTexturedPbrEnvironmentDiffuseInput(vec3 normal) {
|
|
|
2229
2935
|
float horizonBlend = 1.0 - abs(normal.y);
|
|
2230
2936
|
vec3 proceduralDiffuse = mix(u_environmentGroundColor, u_environmentSkyColor, skyBlend);
|
|
2231
2937
|
proceduralDiffuse = mix(proceduralDiffuse, u_environmentHorizonColor, clamp(horizonBlend, 0.0, 1.0) * 0.55);
|
|
2232
|
-
|
|
2938
|
+
// The ambient term must be added to the procedural contribution, not replaced by it. A mix
|
|
2939
|
+
// here discarded u_environmentColor * u_environmentIntensity entirely whenever a procedural
|
|
2940
|
+
// map was present, which is the normal case: raising ambient intensity from 0.18 to 3.0 on
|
|
2941
|
+
// the product-turntable kit produced a byte-identical frame. Ambient and a sky gradient are
|
|
2942
|
+
// separate physical contributions, so they sum.
|
|
2943
|
+
vec3 environmentDiffuse = ambientEnvironment + proceduralDiffuse * u_environmentMapIntensity * proceduralEnvironmentWeight;
|
|
2233
2944
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureIntensity);
|
|
2234
2945
|
float diffuseEnvironmentLod = max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
2235
2946
|
vec3 sampledDiffuse = a3dTexturedPbrDecodeEnvironmentSample(a3dTexturedPbrEnvironmentSampleRaw(normal, diffuseEnvironmentLod));
|
|
2236
|
-
return mix(environmentDiffuse,
|
|
2947
|
+
return mix(environmentDiffuse, ambientEnvironment + sampledDiffuse * u_environmentMapTextureIntensity, sampledEnvironmentWeight);
|
|
2237
2948
|
}
|
|
2238
2949
|
vec3 a3dTexturedPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, float roughness) {
|
|
2239
2950
|
float materialEnvironmentSpecularScale = clamp(u_materialEnvironmentSpecularScale, 0.0, 1.0);
|
|
@@ -2257,7 +2968,6 @@ vec3 a3dTexturedPbrEnvironmentSpecularInput(vec3 normal, vec3 viewDirection, flo
|
|
|
2257
2968
|
float sampledEnvironmentWeight = step(0.0001, u_environmentMapTextureEnabled * u_environmentMapTextureSpecularIntensity);
|
|
2258
2969
|
float environmentLod = clampedRoughness * max(u_environmentMapTextureMipCount - 1.0, 0.0);
|
|
2259
2970
|
vec3 sampledSpecular = a3dTexturedPbrBoundHdrSpecularRadiance(a3dTexturedPbrDecodeEnvironmentSample(a3dTexturedPbrEnvironmentSampleRaw(reflectionDirection, environmentLod)));
|
|
2260
|
-
vec2 brdfLut = texture(u_environmentBrdfLutTexture, vec2(nDotV, clampedRoughness)).rg;
|
|
2261
2971
|
sampledSpecular = a3dTexturedPbrClampSampledSpecularEdgeEnergy(sampledSpecular, nDotV, clampedRoughness);
|
|
2262
2972
|
sampledSpecular *= u_environmentMapTextureSpecularIntensity * sampledEnvironmentWeight * mix(0.84, 0.58, clampedRoughness);
|
|
2263
2973
|
float proceduralSpecularScale = materialFiniteSpecularScale * mix(0.34, 1.0, faceOnSpecularGate);
|
|
@@ -2570,14 +3280,43 @@ void main() {
|
|
|
2570
3280
|
#endif
|
|
2571
3281
|
shaded = mix(shaded, shaded * 0.72 + texturedRefractionRadiance, texturedTransmissionAmount * mix(0.08, 0.58, texturedFallbackEnvironmentTransmissionEnergy));
|
|
2572
3282
|
}
|
|
3283
|
+
#ifndef A3D_PBR_DISABLE_CLUSTERED_LIGHTING
|
|
3284
|
+
ivec2 clusterTile = clamp(ivec2(floor(gl_FragCoord.xy / max(u_clusterViewportSize / u_clusterGridSize, vec2(1.0)))), ivec2(0), ivec2(u_clusterGridSize) - ivec2(1));
|
|
3285
|
+
int clusterIndex = clusterTile.y * int(u_clusterGridSize.x) + clusterTile.x;
|
|
3286
|
+
int count = u_clusteredLightEnabled > 0.5 ? min(int(texelFetch(u_clusterLightIndices, ivec2(0, clusterIndex), 0).g), 64) : min(int(u_lightCount), 16);
|
|
3287
|
+
#else
|
|
2573
3288
|
int count = min(int(u_lightCount), 16);
|
|
2574
|
-
|
|
2575
|
-
|
|
3289
|
+
#endif
|
|
3290
|
+
for (int i = 0; i < 64; ++i) {
|
|
3291
|
+
if (i >= count) break;
|
|
3292
|
+
#ifndef A3D_PBR_DISABLE_CLUSTERED_LIGHTING
|
|
3293
|
+
int lightIndex = u_clusteredLightEnabled > 0.5 ? int(texelFetch(u_clusterLightIndices, ivec2(i, clusterIndex), 0).r) : i;
|
|
3294
|
+
int baseIndex = lightIndex * 6;
|
|
3295
|
+
vec4 colorIntensity = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(0, lightIndex), 0) : u_lightData[baseIndex];
|
|
3296
|
+
vec4 positionRange = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(1, lightIndex), 0) : u_lightData[baseIndex + 1];
|
|
3297
|
+
vec4 directionKind = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(2, lightIndex), 0) : u_lightData[baseIndex + 2];
|
|
3298
|
+
vec4 spotShadowLayer = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(3, lightIndex), 0) : u_lightData[baseIndex + 3];
|
|
3299
|
+
vec4 areaRight = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(4, lightIndex), 0) : u_lightData[baseIndex + 4];
|
|
3300
|
+
vec4 areaUp = u_clusteredLightEnabled > 0.5 ? texelFetch(u_clusterLightData, ivec2(5, lightIndex), 0) : u_lightData[baseIndex + 5];
|
|
3301
|
+
#else
|
|
3302
|
+
int baseIndex = i * 6;
|
|
2576
3303
|
vec4 colorIntensity = u_lightData[baseIndex];
|
|
2577
3304
|
vec4 positionRange = u_lightData[baseIndex + 1];
|
|
2578
3305
|
vec4 directionKind = u_lightData[baseIndex + 2];
|
|
2579
3306
|
vec4 spotShadowLayer = u_lightData[baseIndex + 3];
|
|
3307
|
+
vec4 areaRight = u_lightData[baseIndex + 4];
|
|
3308
|
+
vec4 areaUp = u_lightData[baseIndex + 5];
|
|
3309
|
+
#endif
|
|
2580
3310
|
float kind = directionKind.w;
|
|
3311
|
+
if (kind > 2.5) {
|
|
3312
|
+
shaded += a3dPbrRectAreaLight(
|
|
3313
|
+
v_worldPosition, positionRange.xyz, directionKind.xyz, areaRight.xyz, areaUp.xyz,
|
|
3314
|
+
spotShadowLayer.x, spotShadowLayer.y, positionRange.w,
|
|
3315
|
+
mappedNormal, viewDirection, colorIntensity.rgb, colorIntensity.a,
|
|
3316
|
+
base, metallic, roughness, specular, specularColor
|
|
3317
|
+
) * directTextureOcclusion;
|
|
3318
|
+
continue;
|
|
3319
|
+
}
|
|
2581
3320
|
vec3 lightDirection = -directionKind.xyz;
|
|
2582
3321
|
float attenuation = 1.0;
|
|
2583
3322
|
if (kind > 0.5) {
|
|
@@ -2703,6 +3442,109 @@ void main() {
|
|
|
2703
3442
|
vec3 color = a3dBackgroundDecode(encodedSample) * max(u_environmentBackgroundIntensity, 0.0);
|
|
2704
3443
|
outColor = vec4(a3dBackgroundEncodeOutput(color), 1.0);
|
|
2705
3444
|
}
|
|
3445
|
+
`
|
|
3446
|
+
});
|
|
3447
|
+
library.register({
|
|
3448
|
+
name: DEFAULT_SCREEN_SPACE_LINE_SHADER_NAME,
|
|
3449
|
+
marker: DEFAULT_SCREEN_SPACE_LINE_SHADER_MARKER,
|
|
3450
|
+
vertex: `#version 300 es
|
|
3451
|
+
// ${DEFAULT_SCREEN_SPACE_LINE_SHADER_MARKER}
|
|
3452
|
+
precision highp float;
|
|
3453
|
+
layout(location = 0) in vec3 a_position;
|
|
3454
|
+
layout(location = 10) in vec3 a_lineStart;
|
|
3455
|
+
layout(location = 11) in vec3 a_lineEnd;
|
|
3456
|
+
layout(location = 12) in vec2 a_lineCorner;
|
|
3457
|
+
layout(location = 13) in float a_lineDistance;
|
|
3458
|
+
uniform mat4 u_modelViewProjection;
|
|
3459
|
+
/** Line width in CSS pixels. Multiplied by DPR to reach device pixels. */
|
|
3460
|
+
uniform float u_lineWidth;
|
|
3461
|
+
/** Device-pixel resolution of the render target. */
|
|
3462
|
+
uniform vec2 u_lineResolution;
|
|
3463
|
+
uniform float u_linePixelRatio;
|
|
3464
|
+
/** 0 = butt caps, 1 = square caps extended by half a width past each endpoint. */
|
|
3465
|
+
uniform float u_lineSquareCaps;
|
|
3466
|
+
out vec2 v_lineCorner;
|
|
3467
|
+
out float v_lineDistance;
|
|
3468
|
+
out float v_halfWidthPixels;
|
|
3469
|
+
|
|
3470
|
+
void main() {
|
|
3471
|
+
// a_position holds this vertex's anchor endpoint in world space. It is referenced
|
|
3472
|
+
// with zero weight so the attribute is not optimized out of the linked program:
|
|
3473
|
+
// bounds computation, frustum culling, and the material's attribute contract all
|
|
3474
|
+
// depend on the geometry declaring a real position stream.
|
|
3475
|
+
vec3 anchorWorld = a_position;
|
|
3476
|
+
vec4 clipStart = u_modelViewProjection * vec4(a_lineStart + anchorWorld * 0.0, 1.0);
|
|
3477
|
+
vec4 clipEnd = u_modelViewProjection * vec4(a_lineEnd, 1.0);
|
|
3478
|
+
|
|
3479
|
+
// Guard against a zero or negative w: a vertex behind the eye would otherwise
|
|
3480
|
+
// produce a wildly wrong NDC position and a smeared quad.
|
|
3481
|
+
float wStart = max(abs(clipStart.w), 1e-5);
|
|
3482
|
+
float wEnd = max(abs(clipEnd.w), 1e-5);
|
|
3483
|
+
|
|
3484
|
+
// Project to device pixels. Expansion happens here, so the resulting width is a
|
|
3485
|
+
// pixel quantity and is therefore independent of depth, FOV, and viewport size.
|
|
3486
|
+
vec2 pixelStart = (clipStart.xy / wStart) * 0.5 * u_lineResolution;
|
|
3487
|
+
vec2 pixelEnd = (clipEnd.xy / wEnd) * 0.5 * u_lineResolution;
|
|
3488
|
+
|
|
3489
|
+
vec2 pixelDirection = pixelEnd - pixelStart;
|
|
3490
|
+
float pixelLength = length(pixelDirection);
|
|
3491
|
+
// A segment that projects to a single pixel has no screen direction; pick an
|
|
3492
|
+
// arbitrary axis so the cap still renders instead of collapsing.
|
|
3493
|
+
vec2 direction = pixelLength > 1e-4 ? pixelDirection / pixelLength : vec2(1.0, 0.0);
|
|
3494
|
+
vec2 normal = vec2(-direction.y, direction.x);
|
|
3495
|
+
|
|
3496
|
+
float halfWidth = max(u_lineWidth, 0.0) * max(u_linePixelRatio, 0.0001) * 0.5;
|
|
3497
|
+
v_halfWidthPixels = halfWidth;
|
|
3498
|
+
|
|
3499
|
+
float along = a_lineCorner.y;
|
|
3500
|
+
vec2 anchorPixel = mix(pixelStart, pixelEnd, along);
|
|
3501
|
+
// Square caps push the quad outward along the segment direction so the stroke
|
|
3502
|
+
// extends half a width past each endpoint, matching Three.js LineMaterial behaviour.
|
|
3503
|
+
float capExtension = u_lineSquareCaps > 0.5 ? halfWidth : 0.0;
|
|
3504
|
+
vec2 capOffset = direction * (along > 0.5 ? capExtension : -capExtension);
|
|
3505
|
+
vec2 pixelPosition = anchorPixel + normal * (a_lineCorner.x * halfWidth) + capOffset;
|
|
3506
|
+
|
|
3507
|
+
// Back to clip space, preserving the anchor endpoint's own depth so the line
|
|
3508
|
+
// depth-sorts against the rest of the scene correctly.
|
|
3509
|
+
vec4 anchorClip = along > 0.5 ? clipEnd : clipStart;
|
|
3510
|
+
float anchorW = along > 0.5 ? wEnd : wStart;
|
|
3511
|
+
vec2 ndc = pixelPosition / (0.5 * u_lineResolution);
|
|
3512
|
+
gl_Position = vec4(ndc * anchorW, anchorClip.z, anchorClip.w);
|
|
3513
|
+
|
|
3514
|
+
v_lineCorner = a_lineCorner;
|
|
3515
|
+
v_lineDistance = a_lineDistance;
|
|
3516
|
+
}
|
|
3517
|
+
`,
|
|
3518
|
+
fragment: `#version 300 es
|
|
3519
|
+
// ${DEFAULT_SCREEN_SPACE_LINE_SHADER_MARKER}
|
|
3520
|
+
precision highp float;
|
|
3521
|
+
uniform vec4 u_baseColor;
|
|
3522
|
+
/** Dash period in world units. Zero disables dashing. */
|
|
3523
|
+
uniform float u_lineDashSize;
|
|
3524
|
+
uniform float u_lineGapSize;
|
|
3525
|
+
uniform float u_lineDashOffset;
|
|
3526
|
+
/** 0 = butt/square, 1 = round caps and joins. */
|
|
3527
|
+
uniform float u_lineRoundCaps;
|
|
3528
|
+
in vec2 v_lineCorner;
|
|
3529
|
+
in float v_lineDistance;
|
|
3530
|
+
in float v_halfWidthPixels;
|
|
3531
|
+
out vec4 outColor;
|
|
3532
|
+
|
|
3533
|
+
void main() {
|
|
3534
|
+
if (u_lineDashSize > 0.0) {
|
|
3535
|
+
float period = u_lineDashSize + max(u_lineGapSize, 0.0);
|
|
3536
|
+
float phase = mod(v_lineDistance + u_lineDashOffset, period);
|
|
3537
|
+
// Discard the gap portion of each dash period.
|
|
3538
|
+
if (phase > u_lineDashSize) discard;
|
|
3539
|
+
}
|
|
3540
|
+
if (u_lineRoundCaps > 0.5) {
|
|
3541
|
+
// Round caps: reject fragments outside the unit half-disc at each end. The
|
|
3542
|
+
// corner's x component already spans -1..1 across the stroke width.
|
|
3543
|
+
float acrossStroke = v_lineCorner.x;
|
|
3544
|
+
if (abs(acrossStroke) > 1.0) discard;
|
|
3545
|
+
}
|
|
3546
|
+
outColor = u_baseColor;
|
|
3547
|
+
}
|
|
2706
3548
|
`
|
|
2707
3549
|
});
|
|
2708
3550
|
library.register({
|