@unikia/upe-renderer 0.186.110 → 0.187.11
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 +5 -7
- package/UPSTREAM.md +4 -4
- package/build/three.core.js +853 -277
- package/build/three.module.js +1098 -1280
- package/build/three.tsl.js +41938 -686
- package/build/three.webgpu.js +10604 -49055
- package/build/three.webgpu.nodes.js +9249 -5788
- package/examples/jsm/Addons.js +2 -0
- package/examples/jsm/animation/CCDIKSolver.js +17 -5
- package/examples/jsm/controls/FirstPersonControls.js +1 -1
- package/examples/jsm/controls/OrbitControls.js +27 -14
- package/examples/jsm/csm/CSMShader.js +74 -3
- package/examples/jsm/curves/CurveExtras.js +4 -4
- package/examples/jsm/curves/NURBSCurve.js +14 -0
- package/examples/jsm/exporters/EXRExporter.js +673 -16
- package/examples/jsm/exporters/GLTFExporter.js +4 -4
- package/examples/jsm/exporters/KTX2Exporter.js +1 -1
- package/examples/jsm/exporters/OBJExporter.js +48 -5
- package/examples/jsm/exporters/PLYExporter.js +22 -11
- package/examples/jsm/generators/CityGenerator.js +3 -2
- package/examples/jsm/generators/city/SkyscraperGenerator.js +63 -21
- package/examples/jsm/gpgpu/BitonicSort.js +30 -23
- package/examples/jsm/helpers/VertexTangentsHelper.js +1 -1
- package/examples/jsm/inspector/Extension.js +1 -1
- package/examples/jsm/inspector/Inspector.js +6 -46
- package/examples/jsm/inspector/RendererInspector.js +43 -8
- package/examples/jsm/inspector/Storage.js +49 -0
- package/examples/jsm/inspector/extensions/color-grading/ColorGrading.js +32 -27
- package/examples/jsm/inspector/tabs/Parameters.js +5 -1
- package/examples/jsm/inspector/tabs/Performance.js +22 -7
- package/examples/jsm/inspector/tabs/Settings.js +1 -1
- package/examples/jsm/inspector/tabs/Timeline.js +83 -7
- package/examples/jsm/inspector/tabs/Viewer.js +25 -10
- package/examples/jsm/inspector/ui/Profiler.js +1 -1
- package/examples/jsm/inspector/ui/Style.js +21 -53
- package/examples/jsm/inspector/ui/Values.js +28 -3
- package/examples/jsm/libs/fflate.module.js +83 -56
- package/examples/jsm/libs/mikktspace.README.md +27 -0
- package/examples/jsm/libs/mikktspace.module.js +721 -109
- package/examples/jsm/lighting/ClusteredLighting.js +100 -2
- package/examples/jsm/lighting/LightMapper.js +295 -0
- package/examples/jsm/lighting/LightProbeGrid.js +242 -139
- package/examples/jsm/lighting/LightProbeGridWebGL.js +30 -14
- package/examples/jsm/lighting/vxgi/VXGIConeTracer.js +54 -5
- package/examples/jsm/lighting/vxgi/VXGIIrradiance.js +43 -0
- package/examples/jsm/lighting/vxgi/VXGINode.js +13 -56
- package/examples/jsm/lighting/vxgi/VXGISceneCollector.js +316 -1
- package/examples/jsm/lighting/vxgi/VXGIVolume.js +69 -59
- package/examples/jsm/lights/SunLight.js +9 -4
- package/examples/jsm/lights/SunLightNode.js +3 -3
- package/examples/jsm/lines/LineMaterial.js +26 -10
- package/examples/jsm/loaders/3DMLoader.js +10 -1
- package/examples/jsm/loaders/3MFLoader.js +5 -1
- package/examples/jsm/loaders/AMFLoader.js +2 -0
- package/examples/jsm/loaders/BVHLoader.js +2 -0
- package/examples/jsm/loaders/ColladaLoader.js +8 -0
- package/examples/jsm/loaders/DDSLoader.js +1 -1
- package/examples/jsm/loaders/DRACOLoader.js +5 -1
- package/examples/jsm/loaders/EXRLoader.js +120 -104
- package/examples/jsm/loaders/FBXLoader.js +4 -0
- package/examples/jsm/loaders/FontLoader.js +2 -0
- package/examples/jsm/loaders/GCodeLoader.js +5 -9
- package/examples/jsm/loaders/GLTFLoader.js +112 -31
- package/examples/jsm/loaders/GaussianSplatPLYLoader.js +2 -0
- package/examples/jsm/loaders/HDRCubeTextureLoader.js +3 -0
- package/examples/jsm/loaders/IESLoader.js +46 -12
- package/examples/jsm/loaders/JXLLoader.js +159 -0
- package/examples/jsm/loaders/KMZLoader.js +6 -0
- package/examples/jsm/loaders/KSPLATLoader.js +2 -0
- package/examples/jsm/loaders/KTX2Loader.js +49 -4
- package/examples/jsm/loaders/KTXLoader.js +5 -3
- package/examples/jsm/loaders/LDrawLoader.js +15 -22
- package/examples/jsm/loaders/LUT3dlLoader.js +5 -1
- package/examples/jsm/loaders/LUTCubeLoader.js +6 -2
- package/examples/jsm/loaders/LUTImageLoader.js +2 -0
- package/examples/jsm/loaders/LWOLoader.js +6 -0
- package/examples/jsm/loaders/MD2Loader.js +2 -0
- package/examples/jsm/loaders/MDDLoader.js +4 -0
- package/examples/jsm/loaders/MTLLoader.js +8 -0
- package/examples/jsm/loaders/MaterialXLoader.js +57 -5
- package/examples/jsm/loaders/NRRDLoader.js +4 -2
- package/examples/jsm/loaders/OBJLoader.js +10 -4
- package/examples/jsm/loaders/PCDLoader.js +6 -2
- package/examples/jsm/loaders/PDBLoader.js +5 -3
- package/examples/jsm/loaders/PLYLoader.js +39 -15
- package/examples/jsm/loaders/PVRLoader.js +2 -2
- package/examples/jsm/loaders/SPLATLoader.js +2 -0
- package/examples/jsm/loaders/SPZLoader.js +2 -0
- package/examples/jsm/loaders/STLLoader.js +3 -1
- package/examples/jsm/loaders/SVGLoader.js +27 -49
- package/examples/jsm/loaders/TDSLoader.js +4 -0
- package/examples/jsm/loaders/TGALoader.js +6 -5
- package/examples/jsm/loaders/TTFLoader.js +2 -0
- package/examples/jsm/loaders/USDLoader.js +14 -0
- package/examples/jsm/loaders/UltraHDRLoader.js +2 -0
- package/examples/jsm/loaders/VOXLoader.js +3 -0
- package/examples/jsm/loaders/VRMLLoader.js +4 -0
- package/examples/jsm/loaders/VTKLoader.js +2 -0
- package/examples/jsm/loaders/XYZLoader.js +2 -0
- package/examples/jsm/loaders/collada/ColladaComposer.js +15 -8
- package/examples/jsm/loaders/materialx/MaterialXDocument.js +610 -138
- package/examples/jsm/loaders/materialx/MaterialXInterfaceValidation.js +12 -95
- package/examples/jsm/loaders/materialx/MaterialXLog.js +4 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeDefs.js +99 -0
- package/examples/jsm/loaders/materialx/MaterialXNodeInterfaceRegistry.js +760 -1
- package/examples/jsm/loaders/materialx/MaterialXNodeLibrary.js +222 -372
- package/examples/jsm/loaders/materialx/MaterialXSurfaceMappings.js +163 -259
- package/examples/jsm/loaders/materialx/MaterialXUtils.js +25 -0
- package/examples/jsm/loaders/materialx/compile/MaterialXCompileRegistry.js +161 -159
- package/examples/jsm/loaders/usd/USDAParser.js +56 -47
- package/examples/jsm/loaders/usd/USDComposer.js +25 -30
- package/examples/jsm/math/ColorConverter.js +7 -3
- package/examples/jsm/math/Lut.js +2 -2
- package/examples/jsm/math/OBB.js +3 -3
- package/examples/jsm/math/Octree.js +20 -17
- package/examples/jsm/objects/GaussianSplat.js +5 -4
- package/examples/jsm/objects/Reflector.js +5 -0
- package/examples/jsm/objects/SkyMesh.js +14 -7
- package/examples/jsm/objects/Water2Mesh.js +2 -2
- package/examples/jsm/physics/RapierPhysics.js +2 -2
- package/examples/jsm/pipelines/MeshletDrawingPipeline.js +5571 -0
- package/examples/jsm/pipelines/VisibilityBufferDrawingPipeline.js +954 -0
- package/examples/jsm/postprocessing/BokehPass.js +1 -1
- package/examples/jsm/postprocessing/GTAOPass.js +26 -18
- package/examples/jsm/renderers/SVGRenderer.js +3 -2
- package/examples/jsm/shaders/GTAOShader.js +7 -4
- package/examples/jsm/shaders/PoissonDenoiseShader.js +1 -10
- package/examples/jsm/tsl/WebGLNodesHandler.js +21 -9
- package/examples/jsm/tsl/display/AfterImageNode.js +3 -3
- package/examples/jsm/tsl/display/BilateralBlurNode.js +3 -3
- package/examples/jsm/tsl/display/BloomNode.js +3 -3
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +8 -19
- package/examples/jsm/tsl/display/DenoiseNode.js +5 -5
- package/examples/jsm/tsl/display/DepthOfFieldNode.js +3 -3
- package/examples/jsm/tsl/display/DotScreenNode.js +3 -3
- package/examples/jsm/tsl/display/FSR1Node.js +3 -3
- package/examples/jsm/tsl/display/FXAANode.js +3 -10
- package/examples/jsm/tsl/display/FilmNode.js +3 -3
- package/examples/jsm/tsl/display/GTAONode.js +33 -25
- package/examples/jsm/tsl/display/GaussianBlurNode.js +3 -3
- package/examples/jsm/tsl/display/GodraysNode.js +5 -19
- package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +8 -4
- package/examples/jsm/tsl/display/LensflareNode.js +3 -3
- package/examples/jsm/tsl/display/Lut3DNode.js +3 -3
- package/examples/jsm/tsl/display/OITPassNode.js +0 -11
- package/examples/jsm/tsl/display/OutlineNode.js +107 -5
- package/examples/jsm/tsl/display/PixelationPassNode.js +85 -193
- package/examples/jsm/tsl/display/RGBShiftNode.js +3 -3
- package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +23 -126
- package/examples/jsm/tsl/display/SMAANode.js +3 -3
- package/examples/jsm/tsl/display/SSAONode.js +6 -20
- package/examples/jsm/tsl/display/SSGINode.js +36 -29
- package/examples/jsm/tsl/display/SSRNode.js +135 -63
- package/examples/jsm/tsl/display/SSSNode.js +6 -20
- package/examples/jsm/tsl/display/SharpenNode.js +3 -3
- package/examples/jsm/tsl/display/SobelOperatorNode.js +3 -3
- package/examples/jsm/tsl/display/TAAUNode.js +10 -42
- package/examples/jsm/tsl/display/TRAANode.js +11 -43
- package/examples/jsm/tsl/display/TemporalReprojectNode.js +42 -47
- package/examples/jsm/tsl/display/TransitionNode.js +3 -3
- package/examples/jsm/tsl/display/lensDirt.js +30 -0
- package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +482 -121
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +41 -140
- package/examples/jsm/tsl/lighting/LightProbeGridNode.js +72 -25
- package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +6 -0
- package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +6 -0
- package/examples/jsm/tsl/shadows/TileShadowNode.js +102 -14
- package/examples/jsm/tsl/utils/Raymarching.js +1 -1
- package/examples/jsm/tsl/utils/SoftParticles.js +5 -12
- package/examples/jsm/tsl/utils/SpecularHelpers.js +47 -70
- package/examples/jsm/tsl/utils/TAAUtils.js +6 -17
- package/examples/jsm/utils/BufferGeometryUtils.js +110 -88
- package/examples/jsm/utils/MeshletGeometryUtils.js +417 -0
- package/examples/jsm/utils/SceneOptimizer.js +2 -1
- package/examples/jsm/utils/SceneUtils.js +1 -1
- package/examples/jsm/utils/unwrapUVs.js +865 -0
- package/examples/jsm/webxr/XREstimatedLight.js +11 -4
- package/package.json +3 -3
- package/src/Three.TSL.js +2 -683
- package/src/Three.WebGPU.Nodes.js +2 -1
- package/src/Three.WebGPU.js +2 -1
- package/src/animation/AnimationAction.js +1 -1
- package/src/animation/AnimationUtils.js +1 -3
- package/src/animation/KeyframeTrack.js +19 -0
- package/src/cameras/ArrayCamera.js +12 -0
- package/src/cameras/CubeCamera.js +3 -3
- package/src/constants.js +1 -9
- package/src/core/BufferAttribute.js +57 -21
- package/src/core/BufferGeometry.js +5 -13
- package/src/core/Clock.js +1 -1
- package/src/core/InterleavedBuffer.js +28 -18
- package/src/core/InterleavedBufferAttribute.js +54 -20
- package/src/core/Object3D.js +19 -9
- package/src/core/Raycaster.js +2 -0
- package/src/core/RenderTarget.js +11 -5
- package/src/core/UniformsGroup.js +7 -3
- package/src/extras/PMREMGenerator.js +392 -685
- package/src/extras/core/Curve.js +4 -0
- package/src/extras/core/CurvePath.js +13 -0
- package/src/extras/core/ShapePath.js +1 -1
- package/src/geometries/EdgesGeometry.js +12 -10
- package/src/geometries/LatheGeometry.js +2 -0
- package/src/helpers/PolarGridHelper.js +1 -1
- package/src/lights/Light.js +11 -0
- package/src/lights/LightProbe.js +2 -0
- package/src/lights/LightShadow.js +2 -0
- package/src/loaders/AnimationLoader.js +2 -0
- package/src/loaders/AudioLoader.js +2 -0
- package/src/loaders/BufferGeometryLoader.js +2 -0
- package/src/loaders/CompressedTextureLoader.js +2 -0
- package/src/loaders/CubeTextureLoader.js +2 -0
- package/src/loaders/DataTextureLoader.js +2 -0
- package/src/loaders/FileLoader.js +2 -0
- package/src/loaders/ImageBitmapLoader.js +3 -1
- package/src/loaders/ImageLoader.js +1 -0
- package/src/loaders/Loader.js +47 -0
- package/src/loaders/MaterialLoader.js +2 -0
- package/src/loaders/ObjectLoader.js +27 -8
- package/src/loaders/TextureLoader.js +5 -3
- package/src/loaders/nodes/NodeLoader.js +2 -0
- package/src/materials/Material.js +21 -2
- package/src/materials/MeshDepthMaterial.js +1 -1
- package/src/materials/MeshDistanceMaterial.js +1 -1
- package/src/materials/MeshLambertMaterial.js +1 -1
- package/src/materials/MeshMatcapMaterial.js +1 -1
- package/src/materials/MeshNormalMaterial.js +1 -1
- package/src/materials/MeshPhongMaterial.js +1 -1
- package/src/materials/MeshPhysicalMaterial.js +90 -11
- package/src/materials/MeshStandardMaterial.js +1 -1
- package/src/materials/MeshToonMaterial.js +1 -1
- package/src/materials/nodes/Line2NodeMaterial.js +32 -10
- package/src/materials/nodes/MeshLambertNodeMaterial.js +13 -0
- package/src/materials/nodes/MeshPhongNodeMaterial.js +13 -0
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +40 -5
- package/src/materials/nodes/MeshToonNodeMaterial.js +13 -0
- package/src/materials/nodes/NodeMaterial.js +36 -16
- package/src/materials/nodes/NodeMaterialInstance.js +193 -0
- package/src/materials/nodes/NodeMaterials.js +1 -0
- package/src/materials/nodes/PointsNodeMaterial.js +1 -1
- package/src/materials/nodes/SpriteNodeMaterial.js +3 -3
- package/src/materials/nodes/manager/NodeMaterialObserver.js +191 -22
- package/src/math/Box3.js +2 -2
- package/src/math/Color.js +8 -8
- package/src/math/ColorManagement.js +2 -21
- package/src/math/FrustumArray.js +12 -0
- package/src/math/Interpolant.js +1 -1
- package/src/math/Line3.js +2 -4
- package/src/math/MathUtils.js +33 -46
- package/src/math/Matrix2.js +1 -1
- package/src/math/Matrix3.js +1 -1
- package/src/math/Matrix4.js +1 -1
- package/src/math/Triangle.js +2 -1
- package/src/math/Vector2.js +1 -1
- package/src/math/Vector3.js +1 -1
- package/src/math/Vector4.js +1 -1
- package/src/nodes/Nodes.js +1 -0
- package/src/nodes/TSL.js +2 -0
- package/src/nodes/accessors/Arrays.js +1 -1
- package/src/nodes/accessors/Batch.js +29 -23
- package/src/nodes/accessors/BufferAttributeNode.js +21 -1
- package/src/nodes/accessors/BuiltinNode.js +6 -0
- package/src/nodes/accessors/Camera.js +100 -93
- package/src/nodes/accessors/ClippingNode.js +17 -6
- package/src/nodes/accessors/CubeTextureNode.js +12 -24
- package/src/nodes/accessors/Instance.js +198 -160
- package/src/nodes/accessors/Lights.js +19 -6
- package/src/nodes/accessors/MaterialNode.js +33 -4
- package/src/nodes/accessors/Morph.js +81 -22
- package/src/nodes/accessors/Normal.js +0 -42
- package/src/nodes/accessors/Object3DNode.js +6 -0
- package/src/nodes/accessors/PointUVNode.js +6 -0
- package/src/nodes/accessors/ReferenceAttributeNode.js +279 -0
- package/src/nodes/accessors/ReferenceBaseNode.js +6 -0
- package/src/nodes/accessors/ReferenceNode.js +6 -0
- package/src/nodes/accessors/Skinning.js +57 -52
- package/src/nodes/accessors/StorageBufferNode.js +3 -12
- package/src/nodes/accessors/TextureBicubic.js +30 -27
- package/src/nodes/accessors/TextureNode.js +164 -78
- package/src/nodes/accessors/TextureSizeNode.js +6 -0
- package/src/nodes/accessors/UniformArrayNode.js +8 -15
- package/src/nodes/accessors/VelocityNode.js +13 -8
- package/src/nodes/code/CodeNode.js +6 -0
- package/src/nodes/code/ExpressionNode.js +6 -0
- package/src/nodes/code/FunctionCallNode.js +3 -3
- package/src/nodes/code/FunctionNode.js +15 -13
- package/src/nodes/core/ArrayNode.js +3 -3
- package/src/nodes/core/AssignNode.js +10 -9
- package/src/nodes/core/AttributeNode.js +39 -0
- package/src/nodes/core/BypassNode.js +6 -0
- package/src/nodes/core/ConstNode.js +31 -1
- package/src/nodes/core/ContextNode.js +11 -6
- package/src/nodes/core/IndexNode.js +6 -0
- package/src/nodes/core/InputNode.js +6 -0
- package/src/nodes/core/InspectorNode.js +17 -31
- package/src/nodes/core/IsolateNode.js +8 -0
- package/src/nodes/core/Node.js +367 -67
- package/src/nodes/core/NodeBuilder.js +664 -222
- package/src/nodes/core/NodeUtils.js +25 -0
- package/src/nodes/core/NodeVar.js +10 -1
- package/src/nodes/core/OutputStructNode.js +6 -0
- package/src/nodes/core/OverrideContextNode.js +38 -37
- package/src/nodes/core/PropertyNode.js +14 -0
- package/src/nodes/core/StackNode.js +33 -21
- package/src/nodes/core/StructNode.js +6 -0
- package/src/nodes/core/StructTypeNode.js +6 -0
- package/src/nodes/core/SubBuildNode.js +8 -0
- package/src/nodes/core/TempNode.js +10 -35
- package/src/nodes/core/UniformGroupNode.js +6 -0
- package/src/nodes/core/VarNode.js +43 -135
- package/src/nodes/core/VaryingNode.js +33 -2
- package/src/nodes/display/BlendModes.js +5 -40
- package/src/nodes/display/BumpMapNode.js +17 -7
- package/src/nodes/display/ColorAdjustment.js +22 -10
- package/src/nodes/display/ColorSpaceFunctions.js +2 -14
- package/src/nodes/display/ColorSpaceNode.js +3 -3
- package/src/nodes/display/FrontFacingNode.js +6 -0
- package/src/nodes/display/NormalMapNode.js +3 -3
- package/src/nodes/display/PassNode.js +75 -16
- package/src/nodes/display/RenderOutputNode.js +22 -5
- package/src/nodes/display/ScreenNode.js +6 -0
- package/src/nodes/display/ToneMappingFunctions.js +9 -51
- package/src/nodes/display/ToneMappingNode.js +3 -3
- package/src/nodes/display/ToonOutlinePassNode.js +66 -2
- package/src/nodes/display/ViewportDepthNode.js +34 -4
- package/src/nodes/functions/BSDF/BRDF_EON.js +65 -0
- package/src/nodes/functions/BSDF/BRDF_GGX.js +5 -3
- package/src/nodes/functions/BSDF/BRDF_Sheen.js +2 -16
- package/src/nodes/functions/BSDF/D_GGX.js +1 -8
- package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +7 -10
- package/src/nodes/functions/BSDF/LTC.js +20 -47
- package/src/nodes/functions/BSDF/Schlick_to_F0.js +1 -9
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -9
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +10 -13
- package/src/nodes/functions/PhysicalLightingModel.js +84 -51
- package/src/nodes/functions/VolumetricLightingModel.js +1 -1
- package/src/nodes/functions/material/getAlphaHashThreshold.js +3 -9
- package/src/nodes/functions/material/getParallaxCorrectNormal.js +10 -11
- package/src/nodes/functions/material/getRoughness.js +3 -1
- package/src/nodes/geometry/RangeNode.js +52 -69
- package/src/nodes/gpgpu/AtomicFunctionNode.js +11 -6
- package/src/nodes/gpgpu/BarrierNode.js +6 -0
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +6 -0
- package/src/nodes/gpgpu/ComputeNode.js +6 -0
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +38 -29
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +6 -0
- package/src/nodes/lighting/AnalyticLightNode.js +7 -14
- package/src/nodes/lighting/BasicEnvironmentNode.js +5 -1
- package/src/nodes/lighting/EnvironmentNode.js +58 -8
- package/src/nodes/lighting/IESSpotLightNode.js +19 -4
- package/src/nodes/lighting/LightProbeNode.js +2 -1
- package/src/nodes/lighting/LightUtils.js +2 -2
- package/src/nodes/lighting/LightingNode.js +6 -0
- package/src/nodes/lighting/LightsNode.js +26 -32
- package/src/nodes/lighting/PointShadowNode.js +92 -48
- package/src/nodes/lighting/ProjectorLightNode.js +1 -1
- package/src/nodes/lighting/RectAreaLightNode.js +13 -14
- package/src/nodes/lighting/ShadowBaseNode.js +9 -17
- package/src/nodes/lighting/ShadowFilterNode.js +26 -3
- package/src/nodes/lighting/ShadowNode.js +13 -11
- package/src/nodes/materialx/MaterialXColor.js +2 -14
- package/src/nodes/materialx/MaterialXColorTransform.js +1 -7
- package/src/nodes/materialx/MaterialXNodes.js +8 -11
- package/src/nodes/materialx/MaterialXNoise.js +195 -454
- package/src/nodes/math/BitcastNode.js +5 -5
- package/src/nodes/math/BitcountNode.js +18 -46
- package/src/nodes/math/ConditionalNode.js +92 -22
- package/src/nodes/math/Hash.js +1 -1
- package/src/nodes/math/MathNode.js +86 -64
- package/src/nodes/math/MathUtils.js +2 -2
- package/src/nodes/math/OperatorNode.js +42 -59
- package/src/nodes/math/PackFloatNode.js +9 -9
- package/src/nodes/math/Packed4x8IntegerNode.js +20 -52
- package/src/nodes/math/TriNoise3D.js +3 -23
- package/src/nodes/math/UnpackFloatNode.js +9 -9
- package/src/nodes/pmrem/PMREMNode.js +38 -75
- package/src/nodes/pmrem/PMREMUtils.js +108 -272
- package/src/nodes/procedural/Checker.js +1 -1
- package/src/nodes/tsl/TSLCore.js +199 -74
- package/src/nodes/utils/ArrayElementNode.js +19 -1
- package/src/nodes/utils/CubeMapNode.js +3 -3
- package/src/nodes/utils/DebugNode.js +2 -2
- package/src/nodes/utils/EventNode.js +6 -0
- package/src/nodes/utils/FlipNode.js +3 -3
- package/src/nodes/utils/FunctionOverloadingNode.js +7 -1
- package/src/nodes/utils/JoinNode.js +3 -3
- package/src/nodes/utils/LoopNode.js +14 -9
- package/src/nodes/utils/MemberNode.js +18 -0
- package/src/nodes/utils/PostProcessingUtils.js +20 -25
- package/src/nodes/utils/RTTNode.js +2 -0
- package/src/nodes/utils/ReflectorNode.js +24 -0
- package/src/nodes/utils/RotateNode.js +3 -3
- package/src/nodes/utils/SampleNode.js +6 -0
- package/src/nodes/utils/SetNode.js +3 -3
- package/src/nodes/utils/SplitNode.js +6 -0
- package/src/nodes/utils/UVUtils.js +2 -2
- package/src/objects/BatchedMesh.js +146 -15
- package/src/objects/InstancedMesh.js +12 -4
- package/src/objects/Line.js +20 -0
- package/src/objects/Mesh.js +8 -0
- package/src/objects/Points.js +20 -0
- package/src/objects/Skeleton.js +26 -0
- package/src/objects/SkinnedMesh.js +3 -3
- package/src/objects/Sprite.js +10 -0
- package/src/renderers/WebGLRenderer.js +104 -70
- package/src/renderers/common/Animation.js +5 -1
- package/src/renderers/common/Attributes.js +67 -57
- package/src/renderers/common/Backend.js +78 -3
- package/src/renderers/common/BindGroup.js +11 -0
- package/src/renderers/common/Binding.js +0 -11
- package/src/renderers/common/Bindings.js +116 -10
- package/src/renderers/common/Buffer.js +1 -1
- package/src/renderers/common/ClippingContext.js +12 -1
- package/src/renderers/common/ComputePipeline.js +17 -1
- package/src/renderers/common/DirectRenderPipeline.js +7 -3
- package/src/renderers/common/Geometries.js +170 -132
- package/src/renderers/common/Info.js +1 -1
- package/src/renderers/common/InspectorBase.js +5 -5
- package/src/renderers/common/Lighting.js +59 -0
- package/src/renderers/common/Pipelines.js +26 -12
- package/src/renderers/common/ProgrammableStage.js +1 -17
- package/src/renderers/common/RenderContext.js +21 -0
- package/src/renderers/common/RenderContexts.js +13 -4
- package/src/renderers/common/RenderObject.js +111 -35
- package/src/renderers/common/RenderObjects.js +37 -19
- package/src/renderers/common/Renderer.js +537 -295
- package/src/renderers/common/RendererUtils.js +15 -0
- package/src/renderers/common/StandardDrawingPipeline.js +343 -0
- package/src/renderers/common/Storage3DTexture.js +11 -0
- package/src/renderers/common/StorageArrayTexture.js +10 -0
- package/src/renderers/common/StorageTexture.js +0 -9
- package/src/renderers/common/Textures.js +144 -37
- package/src/renderers/common/UniformsGroup.js +19 -0
- package/src/renderers/common/XRManager.js +10 -91
- package/src/renderers/common/extras/PMREMGenerator.js +298 -576
- package/src/renderers/common/nodes/NodeBuilderState.js +7 -5
- package/src/renderers/common/nodes/NodeLibrary.js +11 -35
- package/src/renderers/common/nodes/NodeManager.js +80 -31
- package/src/renderers/common/nodes/NodeSampledTexture.js +14 -0
- package/src/renderers/common/nodes/NodeSampler.js +14 -0
- package/src/renderers/common/nodes/NodeStorageBuffer.js +1 -1
- package/src/renderers/common/nodes/NodeUniformBuffer.js +1 -14
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +13 -4
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +8 -8
- package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +23 -11
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +21 -2
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +18 -2
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +104 -7
- package/src/renderers/shaders/ShaderChunk/morphcolor_vertex.glsl.js +11 -2
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +36 -20
- package/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js +5 -0
- package/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js +5 -0
- package/src/renderers/shaders/ShaderChunk.js +0 -2
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +4 -18
- package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +0 -1
- package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +0 -1
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +8 -1
- package/src/renderers/shaders/ShaderLib.js +3 -0
- package/src/renderers/shaders/UniformsLib.js +4 -5
- package/src/renderers/webgl/WebGLBackground.js +3 -3
- package/src/renderers/webgl/WebGLBindingStates.js +4 -2
- package/src/renderers/webgl/WebGLCapabilities.js +7 -1
- package/src/renderers/webgl/WebGLEnvironments.js +2 -2
- package/src/renderers/webgl/WebGLGeometries.js +42 -14
- package/src/renderers/webgl/WebGLMaterials.js +15 -2
- package/src/renderers/webgl/WebGLOutput.js +37 -1
- package/src/renderers/webgl/WebGLProgram.js +13 -54
- package/src/renderers/webgl/WebGLPrograms.js +22 -8
- package/src/renderers/webgl/WebGLRenderStates.js +11 -8
- package/src/renderers/webgl/WebGLShadowMap.js +6 -4
- package/src/renderers/webgl/WebGLState.js +10 -6
- package/src/renderers/webgl/WebGLTextures.js +129 -77
- package/src/renderers/webgl/WebGLUniforms.js +44 -6
- package/src/renderers/webgl/WebGLUniformsGroups.js +75 -69
- package/src/renderers/webgl-fallback/WebGLBackend.js +206 -278
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +154 -20
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +45 -42
- package/src/renderers/webgl-fallback/utils/WebGLState.js +29 -4
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +129 -49
- package/src/renderers/webgl-fallback/utils/WebGLVertexArrayUtils.js +346 -0
- package/src/renderers/webgpu/WebGPUBackend.js +140 -82
- package/src/renderers/webgpu/WebGPURenderer.js +1 -1
- package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +10 -10
- package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +10 -10
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +135 -60
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +128 -55
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +15 -12
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +55 -19
- package/src/renderers/webgpu/utils/WebGPUUtils.js +20 -3
- package/src/renderers/webxr/WebXRController.js +3 -3
- package/src/renderers/webxr/WebXRManager.js +5 -90
- package/src/scenes/Scene.js +4 -4
- package/src/textures/CompressedTexture.js +2 -2
- package/src/textures/DepthTexture.js +2 -2
- package/src/textures/FramebufferTexture.js +11 -0
- package/src/textures/Texture.js +29 -1
- package/src/textures/TextureSource.js +1 -1
- package/src/upe.js +1 -1
- package/src/utils.js +4 -4
- package/examples/jsm/libs/surfaceNet.js +0 -201
- package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -186
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
Data3DTexture,
|
|
5
5
|
FloatType,
|
|
6
6
|
HalfFloatType,
|
|
7
|
+
Light,
|
|
7
8
|
LinearFilter,
|
|
8
9
|
MathUtils,
|
|
9
10
|
Mesh,
|
|
10
11
|
NearestFilter,
|
|
11
|
-
Object3D,
|
|
12
12
|
OrthographicCamera,
|
|
13
13
|
PlaneGeometry,
|
|
14
14
|
RGBAFormat,
|
|
@@ -85,23 +85,25 @@ const ATLAS_PADDING = 1;
|
|
|
85
85
|
*
|
|
86
86
|
* @three_import import { LightProbeGridWebGL } from 'three/addons/lighting/LightProbeGridWebGL.js';
|
|
87
87
|
*/
|
|
88
|
-
class LightProbeGridWebGL extends
|
|
88
|
+
class LightProbeGridWebGL extends Light {
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
91
|
* Constructs a new irradiance probe grid.
|
|
92
92
|
*
|
|
93
|
-
* The volume is centered at the object's position.
|
|
93
|
+
* The volume is centered at the object's position. It is split into one cell
|
|
94
|
+
* per probe, with each probe at the center of its cell, so the probes sit half
|
|
95
|
+
* a cell inside the volume.
|
|
94
96
|
*
|
|
95
97
|
* @param {number} [width=1] - Full width of the volume along X.
|
|
96
98
|
* @param {number} [height=1] - Full height of the volume along Y.
|
|
97
99
|
* @param {number} [depth=1] - Full depth of the volume along Z.
|
|
98
|
-
* @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max(
|
|
99
|
-
* @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max(
|
|
100
|
-
* @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max(
|
|
100
|
+
* @param {number} [widthProbes] - Number of probes along X. Defaults to `Math.max( 1, Math.round( width ) )`.
|
|
101
|
+
* @param {number} [heightProbes] - Number of probes along Y. Defaults to `Math.max( 1, Math.round( height ) )`.
|
|
102
|
+
* @param {number} [depthProbes] - Number of probes along Z. Defaults to `Math.max( 1, Math.round( depth ) )`.
|
|
101
103
|
*/
|
|
102
104
|
constructor( width = 1, height = 1, depth = 1, widthProbes, heightProbes, depthProbes ) {
|
|
103
105
|
|
|
104
|
-
super();
|
|
106
|
+
super( 0xffffff, 1 );
|
|
105
107
|
|
|
106
108
|
/**
|
|
107
109
|
* This flag can be used for type testing.
|
|
@@ -112,6 +114,8 @@ class LightProbeGridWebGL extends Object3D {
|
|
|
112
114
|
*/
|
|
113
115
|
this.isLightProbeGrid = true;
|
|
114
116
|
|
|
117
|
+
this.type = 'LightProbeGridWebGL';
|
|
118
|
+
|
|
115
119
|
/**
|
|
116
120
|
* The full width of the volume along X.
|
|
117
121
|
*
|
|
@@ -139,19 +143,29 @@ class LightProbeGridWebGL extends Object3D {
|
|
|
139
143
|
* @type {Vector3}
|
|
140
144
|
*/
|
|
141
145
|
this.resolution = new Vector3(
|
|
142
|
-
widthProbes !== undefined ? widthProbes : Math.max(
|
|
143
|
-
heightProbes !== undefined ? heightProbes : Math.max(
|
|
144
|
-
depthProbes !== undefined ? depthProbes : Math.max(
|
|
146
|
+
widthProbes !== undefined ? widthProbes : Math.max( 1, Math.round( width ) ),
|
|
147
|
+
heightProbes !== undefined ? heightProbes : Math.max( 1, Math.round( height ) ),
|
|
148
|
+
depthProbes !== undefined ? depthProbes : Math.max( 1, Math.round( depth ) )
|
|
145
149
|
);
|
|
146
150
|
|
|
147
151
|
/**
|
|
148
|
-
* The world-space bounding box for the grid.
|
|
152
|
+
* The world-space bounding box for the grid. This is the volume the grid
|
|
153
|
+
* lights, with the probes half a cell inside it. Updated automatically
|
|
149
154
|
* by {@link LightProbeGridWebGL#bake}.
|
|
150
155
|
*
|
|
151
156
|
* @type {Box3}
|
|
152
157
|
*/
|
|
153
158
|
this.boundingBox = new Box3();
|
|
154
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Where grids overlap, the grid with the highest priority lights the
|
|
162
|
+
* fragment. On ties, the most recently created grid wins.
|
|
163
|
+
*
|
|
164
|
+
* @type {number}
|
|
165
|
+
* @default 0
|
|
166
|
+
*/
|
|
167
|
+
this.priority = 0;
|
|
168
|
+
|
|
155
169
|
/**
|
|
156
170
|
* The single RGBA atlas 3D texture storing all seven packed SH sub-volumes.
|
|
157
171
|
*
|
|
@@ -193,9 +207,9 @@ class LightProbeGridWebGL extends Object3D {
|
|
|
193
207
|
const w = this.width, h = this.height, d = this.depth;
|
|
194
208
|
|
|
195
209
|
target.set(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
210
|
+
pos.x - w / 2 + ( ix + 0.5 ) * w / res.x,
|
|
211
|
+
pos.y - h / 2 + ( iy + 0.5 ) * h / res.y,
|
|
212
|
+
pos.z - d / 2 + ( iz + 0.5 ) * d / res.z
|
|
199
213
|
);
|
|
200
214
|
|
|
201
215
|
return target;
|
|
@@ -553,6 +567,8 @@ class LightProbeGridWebGL extends Object3D {
|
|
|
553
567
|
|
|
554
568
|
}
|
|
555
569
|
|
|
570
|
+
super.dispose();
|
|
571
|
+
|
|
556
572
|
}
|
|
557
573
|
|
|
558
574
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { float, vec3, vec4, If, Loop, Break, max, min, abs, dot, clamp, log2, exp2, select } from 'three/tsl';
|
|
1
|
+
import { float, vec3, vec4, If, Loop, Break, max, min, abs, dot, cross, normalize, clamp, log2, exp2, fract, sqrt, cos, sin, select, EPSILON, PI } from 'three/tsl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Emits the intersection of a ray with the bounds of the given volume.
|
|
@@ -14,9 +14,9 @@ export function intersectVolume( volume, origin, direction ) {
|
|
|
14
14
|
const boundsMax = boundsMin.add( volume.volumeSizeNode ).toConst();
|
|
15
15
|
|
|
16
16
|
const safeDirection = vec3(
|
|
17
|
-
select( abs( direction.x ).lessThan(
|
|
18
|
-
select( abs( direction.y ).lessThan(
|
|
19
|
-
select( abs( direction.z ).lessThan(
|
|
17
|
+
select( abs( direction.x ).lessThan( EPSILON ), EPSILON, direction.x ),
|
|
18
|
+
select( abs( direction.y ).lessThan( EPSILON ), EPSILON, direction.y ),
|
|
19
|
+
select( abs( direction.z ).lessThan( EPSILON ), EPSILON, direction.z )
|
|
20
20
|
).toConst();
|
|
21
21
|
|
|
22
22
|
const invDirection = float( 1 ).div( safeDirection ).toConst();
|
|
@@ -118,7 +118,7 @@ export function createConeTracer( volume, options = {} ) {
|
|
|
118
118
|
|
|
119
119
|
// AO falloff 1 / ( 1 + r / aoDistance )
|
|
120
120
|
|
|
121
|
-
const aoFalloff = aoDistance !== null ? select( aoDistance.greaterThan( 0 ), float( 1 ).div( max( aoDistance,
|
|
121
|
+
const aoFalloff = aoDistance !== null ? select( aoDistance.greaterThan( 0 ), float( 1 ).div( max( aoDistance, EPSILON ) ), float( 0 ) ).toConst() : null;
|
|
122
122
|
|
|
123
123
|
If( tExit.greaterThan( t ), () => {
|
|
124
124
|
|
|
@@ -192,3 +192,52 @@ export function createConeTracer( volume, options = {} ) {
|
|
|
192
192
|
};
|
|
193
193
|
|
|
194
194
|
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Emits a diffuse gather: Traces stratified cosine-weighted cones around the normal and averages them.
|
|
198
|
+
*
|
|
199
|
+
* @param {Function} trace - The cone tracing function, see {@link createConeTracer}.
|
|
200
|
+
* @param {Node<vec3>} origin - The origin of the cones.
|
|
201
|
+
* @param {Node<vec3>} normal - The normalized surface normal.
|
|
202
|
+
* @param {Node<uint>|number} coneCount - The number of cones.
|
|
203
|
+
* @param {Node<float>} tanHalfAngle - The tangent of half the cone angle.
|
|
204
|
+
* @param {Node<float>} maxDistance - The maximum trace distance.
|
|
205
|
+
* @param {Node<float>|number} rotation - Rotation of the cones around the normal in `[0, 1)`.
|
|
206
|
+
* @param {Node<float>|number} elevation - Offset of the cones within their elevation strata in `[0, 1)`.
|
|
207
|
+
* @param {?Node<float>} [aoDistance=null] - The AO falloff distance. AO is only computed if given.
|
|
208
|
+
* @return {{color: Node<vec3>, ao: Node<float>}} The mean radiance and the mean AO of the cones.
|
|
209
|
+
*/
|
|
210
|
+
export function gather( trace, origin, normal, coneCount, tanHalfAngle, maxDistance, rotation, elevation, aoDistance = null ) {
|
|
211
|
+
|
|
212
|
+
// tangent frame
|
|
213
|
+
|
|
214
|
+
const up = select( abs( normal.y ).lessThan( 0.99 ), vec3( 0, 1, 0 ), vec3( 1, 0, 0 ) );
|
|
215
|
+
const tangent = normalize( cross( normal, up ) ).toConst();
|
|
216
|
+
const bitangent = cross( normal, tangent ).toConst();
|
|
217
|
+
|
|
218
|
+
const color = vec3( 0 ).toVar();
|
|
219
|
+
const ao = float( 0 ).toVar();
|
|
220
|
+
|
|
221
|
+
Loop( { start: 0, end: coneCount, type: 'uint', condition: '<', name: 'c' }, ( { c } ) => {
|
|
222
|
+
|
|
223
|
+
// stratified cosine-weighted directions
|
|
224
|
+
|
|
225
|
+
const u1 = float( c ).add( elevation ).div( float( coneCount ) ).toConst();
|
|
226
|
+
const u2 = fract( float( c ).mul( 0.618034 ).add( rotation ) ).toConst();
|
|
227
|
+
const sinTheta = sqrt( u1 ).toConst();
|
|
228
|
+
const cosTheta = sqrt( u1.oneMinus() ).toConst();
|
|
229
|
+
const phi = u2.mul( PI.mul( 2 ) ).toConst();
|
|
230
|
+
|
|
231
|
+
const direction = normalize( tangent.mul( cos( phi ).mul( sinTheta ) ).add( bitangent.mul( sin( phi ).mul( sinTheta ) ) ).add( normal.mul( cosTheta ) ) ).toConst();
|
|
232
|
+
|
|
233
|
+
const cone = trace( origin, direction, tanHalfAngle, maxDistance, aoDistance );
|
|
234
|
+
|
|
235
|
+
color.addAssign( cone.color );
|
|
236
|
+
|
|
237
|
+
if ( aoDistance !== null ) ao.addAssign( cone.ao );
|
|
238
|
+
|
|
239
|
+
} );
|
|
240
|
+
|
|
241
|
+
return { color: color.div( float( coneCount ) ), ao: ao.div( float( coneCount ) ) };
|
|
242
|
+
|
|
243
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Fn, PI, float, interleavedGradientNoise, screenCoordinate, vec2 } from 'three/tsl';
|
|
2
|
+
import { createConeTracer, gather } from './VXGIConeTracer.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a world-space diffuse irradiance sampler for a prepared {@link VXGIVolume}.
|
|
6
|
+
* Call `volume.update( renderer, scene )` before baking. The sampler traces cosine-weighted
|
|
7
|
+
* cones through the volume's radiance, including cached bounces.
|
|
8
|
+
* It can be passed directly to {@link LightMapper}, without a screen-space pass.
|
|
9
|
+
* The cones are rotated per pixel with interleaved gradient noise like `VXGINode`. When baking, the
|
|
10
|
+
* pixel is the light map texel. The optional sample index shifts the noise so that accumulated
|
|
11
|
+
* samples, or a temporal filter like TRAA, converge.
|
|
12
|
+
*
|
|
13
|
+
* @param {VXGIVolume} volume - The prepared voxel volume.
|
|
14
|
+
* @param {Object} [options] - Options.
|
|
15
|
+
* @param {number} [options.coneCount=8] - The number of cones per sample. Fewer cones are faster but coarser.
|
|
16
|
+
* @return {function(Node<vec3>, Node<vec3>, ?Node<float>): Node<vec3>} The irradiance sampler.
|
|
17
|
+
*/
|
|
18
|
+
function vxgiIrradiance( volume, { coneCount = 8 } = {} ) {
|
|
19
|
+
|
|
20
|
+
const trace = createConeTracer( volume, {
|
|
21
|
+
radianceNode: volume.radianceNode,
|
|
22
|
+
directionalNode: volume.directionalRadiance ? volume.directionalNode : null
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
return ( position, normal, sample = float( 0 ) ) => Fn( () => {
|
|
26
|
+
|
|
27
|
+
// interleaved gradient noise offsets of the stratified cone set, see VXGINode
|
|
28
|
+
|
|
29
|
+
const shift = screenCoordinate.add( sample.mul( 5.588238 ) ).toConst();
|
|
30
|
+
const elevation = interleavedGradientNoise( shift.add( vec2( 5.588238, 3.14159 ) ) ).toConst();
|
|
31
|
+
const rotation = interleavedGradientNoise( shift ).toConst();
|
|
32
|
+
|
|
33
|
+
const origin = position.add( normal.mul( volume.voxelSizeNode.mul( 1.5 ) ) ).toConst();
|
|
34
|
+
|
|
35
|
+
const { color } = gather( trace, origin, normal, coneCount, float( Math.tan( Math.PI / 9 ) ), volume.traceDistanceNode, rotation, elevation );
|
|
36
|
+
|
|
37
|
+
return color.mul( PI );
|
|
38
|
+
|
|
39
|
+
} )();
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { vxgiIrradiance };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { RenderTarget, Vector2, Vector3,
|
|
2
|
-
import { Fn, NodeUpdateType, uniform, reference, vec2,
|
|
1
|
+
import { RenderTarget, Vector2, Vector3, Node, QuadMesh, NodeMaterial, RendererUtils, HalfFloatType, RGBAFormat, RedFormat, UnsignedByteType } from 'three/webgpu';
|
|
2
|
+
import { Fn, NodeUpdateType, uniform, reference, vec2, vec4, float, uv, mix, passTexture, getViewPosition, getNormalFromDepth, screenCoordinate, interleavedGradientNoise, normalize, floor, exp2, pow, PI, Loop, If, Break, property, outputStruct, context, projectionDepth } from 'three/tsl';
|
|
3
3
|
|
|
4
4
|
import { VXGIVolume } from './VXGIVolume.js';
|
|
5
|
-
import { createConeTracer, intersectVolume, sampleDirectional } from './VXGIConeTracer.js';
|
|
5
|
+
import { createConeTracer, gather, intersectVolume, sampleDirectional } from './VXGIConeTracer.js';
|
|
6
6
|
|
|
7
7
|
const _quadMesh = /*@__PURE__*/ new QuadMesh();
|
|
8
8
|
const _size = /*@__PURE__*/ new Vector2();
|
|
@@ -40,10 +40,10 @@ const _neutralContext = /*@__PURE__*/ context();
|
|
|
40
40
|
*
|
|
41
41
|
* Note: This node can only be used with `WebGPURenderer` and a WebGPU backend.
|
|
42
42
|
*
|
|
43
|
-
* @augments
|
|
43
|
+
* @augments Node
|
|
44
44
|
* @three_import import { vxgi } from 'three/addons/lighting/vxgi/VXGINode.js';
|
|
45
45
|
*/
|
|
46
|
-
class VXGINode extends
|
|
46
|
+
class VXGINode extends Node {
|
|
47
47
|
|
|
48
48
|
static get type() {
|
|
49
49
|
|
|
@@ -380,7 +380,7 @@ class VXGINode extends TempNode {
|
|
|
380
380
|
|
|
381
381
|
if ( this._sharedContext !== null && this._directional !== this.volume.directionalRadiance ) {
|
|
382
382
|
|
|
383
|
-
this._setupMaterial(
|
|
383
|
+
this._setupMaterial();
|
|
384
384
|
|
|
385
385
|
}
|
|
386
386
|
|
|
@@ -425,7 +425,7 @@ class VXGINode extends TempNode {
|
|
|
425
425
|
setup( builder ) {
|
|
426
426
|
|
|
427
427
|
this._sharedContext = builder.getSharedContext();
|
|
428
|
-
this._setupMaterial(
|
|
428
|
+
this._setupMaterial();
|
|
429
429
|
|
|
430
430
|
return this._aoNode;
|
|
431
431
|
|
|
@@ -435,29 +435,14 @@ class VXGINode extends TempNode {
|
|
|
435
435
|
* Builds the TSL code of the effect into the internal pass material.
|
|
436
436
|
*
|
|
437
437
|
* @private
|
|
438
|
-
* @param {Renderer} renderer - The renderer.
|
|
439
438
|
*/
|
|
440
|
-
_setupMaterial(
|
|
439
|
+
_setupMaterial() {
|
|
441
440
|
|
|
442
441
|
const volume = this.volume;
|
|
443
442
|
const directional = this._directional = volume.directionalRadiance;
|
|
444
443
|
const uvNode = uv();
|
|
445
444
|
|
|
446
|
-
const sampleDepth = ( uv ) =>
|
|
447
|
-
|
|
448
|
-
const depth = this.depthNode.sample( uv ).r;
|
|
449
|
-
|
|
450
|
-
if ( renderer.logarithmicDepthBuffer === true ) {
|
|
451
|
-
|
|
452
|
-
const viewZ = logarithmicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
|
|
453
|
-
|
|
454
|
-
return viewZToPerspectiveDepth( viewZ, this._cameraNear, this._cameraFar );
|
|
455
|
-
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
return depth;
|
|
459
|
-
|
|
460
|
-
};
|
|
445
|
+
const sampleDepth = ( uv ) => projectionDepth( this.depthNode.sample( uv ).r, this._cameraNear, this._cameraFar );
|
|
461
446
|
|
|
462
447
|
const sampleNormal = ( uv ) => ( this.normalNode !== null ) ? this.normalNode.sample( uv ).rgb.normalize() : getNormalFromDepth( uv, this.depthNode.value, this._cameraProjectionMatrixInverse );
|
|
463
448
|
|
|
@@ -491,47 +476,19 @@ class VXGINode extends TempNode {
|
|
|
491
476
|
const rotationNoise = interleavedGradientNoise( screenCoordinate.add( temporalShift ) ).toConst();
|
|
492
477
|
const elevationNoise = interleavedGradientNoise( screenCoordinate.add( temporalShift ).add( vec2( 5.588238, 3.14159 ) ) ).toConst();
|
|
493
478
|
|
|
494
|
-
// tangent frame
|
|
495
|
-
|
|
496
|
-
const up = select( abs( worldNormal.y ).lessThan( 0.99 ), vec3( 0, 1, 0 ), vec3( 1, 0, 0 ) );
|
|
497
|
-
const tangent = normalize( cross( worldNormal, up ) ).toConst();
|
|
498
|
-
const bitangent = cross( worldNormal, tangent ).toConst();
|
|
499
|
-
|
|
500
479
|
const CONE_COUNT = this.coneCount.toConst();
|
|
501
480
|
const tanHalfAngle = this.coneAngle.mul( 0.5 ).radians().tan().toConst();
|
|
502
481
|
const traceDistance = volume.traceDistanceNode;
|
|
503
482
|
const aoDistance = this.aoDistance;
|
|
504
|
-
const
|
|
483
|
+
const origin = worldPosition.add( worldNormal.mul( voxelSize.mul( this.normalOffset ) ) ).toConst();
|
|
505
484
|
|
|
506
|
-
const color =
|
|
507
|
-
const occlusion = float( 0 ).toVar();
|
|
508
|
-
|
|
509
|
-
Loop( { start: uint( 0 ), end: CONE_COUNT, type: 'uint', condition: '<', name: 'c' }, ( { c } ) => {
|
|
510
|
-
|
|
511
|
-
// stratified cosine-weighted directions
|
|
512
|
-
|
|
513
|
-
const u1 = float( c ).add( elevationNoise ).div( float( CONE_COUNT ) ).toConst();
|
|
514
|
-
const u2 = fract( float( c ).mul( 0.618034 ).add( rotationNoise ) ).toConst();
|
|
515
|
-
const sinTheta = sqrt( u1 ).toConst();
|
|
516
|
-
const cosTheta = sqrt( u1.oneMinus() ).toConst();
|
|
517
|
-
const phi = u2.mul( PI.mul( 2 ) ).toConst();
|
|
518
|
-
|
|
519
|
-
const direction = normalize( tangent.mul( cos( phi ).mul( sinTheta ) ).add( bitangent.mul( sin( phi ).mul( sinTheta ) ) ).add( worldNormal.mul( cosTheta ) ) ).toConst();
|
|
520
|
-
const origin = worldPosition.add( originOffset ).toConst();
|
|
521
|
-
|
|
522
|
-
const cone = trace( origin, direction, tanHalfAngle, traceDistance, aoDistance );
|
|
523
|
-
|
|
524
|
-
color.addAssign( cone.color );
|
|
525
|
-
occlusion.addAssign( cone.ao );
|
|
526
|
-
|
|
527
|
-
} );
|
|
485
|
+
const { color: radiance, ao: occlusion } = gather( trace, origin, worldNormal, CONE_COUNT, tanHalfAngle, traceDistance, rotationNoise, elevationNoise, aoDistance );
|
|
528
486
|
|
|
529
487
|
// the mean radiance over the cosine-weighted hemisphere times PI is the irradiance
|
|
530
488
|
|
|
531
|
-
color.
|
|
532
|
-
color.mulAssign( this.giIntensity.mul( PI ) );
|
|
489
|
+
const color = radiance.mul( this.giIntensity.mul( PI ) ).toVar();
|
|
533
490
|
|
|
534
|
-
const ao = mix( this.aoMinVisibility, float( 1 ), pow( occlusion.
|
|
491
|
+
const ao = mix( this.aoMinVisibility, float( 1 ), pow( occlusion.oneMinus().clamp(), this.aoIntensity ) ).toVar();
|
|
535
492
|
|
|
536
493
|
// debug visualization: march the voxels from the camera
|
|
537
494
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box3, Color, Matrix4, Vector2, Vector3, BackSide, DoubleSide, SRGBColorSpace } from 'three/webgpu';
|
|
1
|
+
import { Box3, Color, MathUtils, Matrix4, Vector2, Vector3, BackSide, DoubleSide, FrontSide, SRGBColorSpace } from 'three/webgpu';
|
|
2
2
|
|
|
3
3
|
const _matrix = /*@__PURE__*/ new Matrix4();
|
|
4
4
|
const _box = /*@__PURE__*/ new Box3();
|
|
@@ -12,8 +12,10 @@ const _uv = /*@__PURE__*/ new Vector2();
|
|
|
12
12
|
const _color = /*@__PURE__*/ new Color();
|
|
13
13
|
const _albedo = /*@__PURE__*/ new Color();
|
|
14
14
|
const _emissive = /*@__PURE__*/ new Color();
|
|
15
|
+
const _columns = /*@__PURE__*/ new Map();
|
|
15
16
|
|
|
16
17
|
const IMAGE_SAMPLE_SIZE = 64;
|
|
18
|
+
const POSITION_QUANTIZATION = 131072;
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Number of floats per triangle record: three positions (vec4 each, w unused),
|
|
@@ -476,3 +478,316 @@ export function collectSceneTriangles( scene, options ) {
|
|
|
476
478
|
return { data, count: data.length / TRIANGLE_STRIDE };
|
|
477
479
|
|
|
478
480
|
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Marks the sub-voxels inside closed meshes, so cones starting within an object are blocked. Only meshes
|
|
484
|
+
* with visible, opaque and single-sided materials whose geometry is closed and faces outwards are filled.
|
|
485
|
+
*
|
|
486
|
+
* @param {Scene} scene - The scene.
|
|
487
|
+
* @param {Object} options - Options.
|
|
488
|
+
* @param {Vector3} options.boundsMin - The minimum corner of the voxel grid.
|
|
489
|
+
* @param {number} options.voxelSize - The size of a voxel in world units.
|
|
490
|
+
* @param {Vector3} options.gridSize - The number of voxels per axis.
|
|
491
|
+
* @param {Layers} options.layers - Objects must pass this layer test.
|
|
492
|
+
* @param {Set<Object3D>} options.exclude - Objects to skip.
|
|
493
|
+
* @param {Uint8Array} target - One byte per voxel that receives the 2x2x2 sub-voxel bits of the interiors.
|
|
494
|
+
*/
|
|
495
|
+
export function computeSolidVoxels( scene, options, target ) {
|
|
496
|
+
|
|
497
|
+
const { boundsMin, voxelSize, gridSize, layers, exclude } = options;
|
|
498
|
+
|
|
499
|
+
const closedGeometries = new Map();
|
|
500
|
+
|
|
501
|
+
scene.traverseVisible( ( object ) => {
|
|
502
|
+
|
|
503
|
+
if ( isVoxelizable( object, layers, exclude ) === false || hasSolidMaterials( object ) === false ) return;
|
|
504
|
+
|
|
505
|
+
const geometry = object.geometry;
|
|
506
|
+
|
|
507
|
+
if ( closedGeometries.has( geometry ) === false ) closedGeometries.set( geometry, isClosed( geometry ) && facesOutwards( geometry ) );
|
|
508
|
+
|
|
509
|
+
if ( closedGeometries.get( geometry ) === false ) return;
|
|
510
|
+
|
|
511
|
+
if ( object.isInstancedMesh === true ) {
|
|
512
|
+
|
|
513
|
+
for ( let i = 0; i < object.count; i ++ ) {
|
|
514
|
+
|
|
515
|
+
object.getMatrixAt( i, _matrix );
|
|
516
|
+
_matrix.premultiply( object.matrixWorld );
|
|
517
|
+
fillInterior( geometry, _matrix, boundsMin, voxelSize, gridSize, target );
|
|
518
|
+
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
} else {
|
|
522
|
+
|
|
523
|
+
fillInterior( geometry, object.matrixWorld, boundsMin, voxelSize, gridSize, target );
|
|
524
|
+
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
} );
|
|
528
|
+
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Returns `true` if all materials of the mesh render an opaque, single-sided surface.
|
|
533
|
+
*
|
|
534
|
+
* @private
|
|
535
|
+
*/
|
|
536
|
+
function hasSolidMaterials( mesh ) {
|
|
537
|
+
|
|
538
|
+
const materials = Array.isArray( mesh.material ) ? mesh.material : [ mesh.material ];
|
|
539
|
+
|
|
540
|
+
for ( const material of materials ) {
|
|
541
|
+
|
|
542
|
+
if ( material.visible === false || material.side !== FrontSide || material.transparent === true || material.alphaTest > 0 ) return false;
|
|
543
|
+
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return true;
|
|
547
|
+
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Returns `true` if every edge of the geometry is shared by an even number of triangles. Vertices with
|
|
552
|
+
* the same position (e.g. at uv seams) are treated as one vertex.
|
|
553
|
+
*
|
|
554
|
+
* @private
|
|
555
|
+
*/
|
|
556
|
+
function isClosed( geometry ) {
|
|
557
|
+
|
|
558
|
+
const position = geometry.getAttribute( 'position' );
|
|
559
|
+
|
|
560
|
+
if ( position === undefined ) return false;
|
|
561
|
+
|
|
562
|
+
const index = geometry.index;
|
|
563
|
+
const indices = index !== null ? index.array : null;
|
|
564
|
+
const count = index !== null ? index.count : position.count;
|
|
565
|
+
|
|
566
|
+
_box.setFromBufferAttribute( position );
|
|
567
|
+
|
|
568
|
+
const min = _box.min;
|
|
569
|
+
const size = _box.getSize( _vb );
|
|
570
|
+
const scaleX = POSITION_QUANTIZATION / Math.max( size.x, 1e-9 );
|
|
571
|
+
const scaleY = POSITION_QUANTIZATION / Math.max( size.y, 1e-9 );
|
|
572
|
+
const scaleZ = POSITION_QUANTIZATION / Math.max( size.z, 1e-9 );
|
|
573
|
+
|
|
574
|
+
const vertexMask = MathUtils.ceilPowerOfTwo( Math.max( position.count, 1 ) * 2 ) - 1;
|
|
575
|
+
const vertexKeys = new Int32Array( ( vertexMask + 1 ) * 3 );
|
|
576
|
+
const vertexSlots = new Int32Array( vertexMask + 1 ).fill( - 1 );
|
|
577
|
+
const vertexIds = new Int32Array( position.count );
|
|
578
|
+
let vertexCount = 0;
|
|
579
|
+
|
|
580
|
+
for ( let i = 0; i < position.count; i ++ ) {
|
|
581
|
+
|
|
582
|
+
const x = Math.round( ( position.getX( i ) - min.x ) * scaleX );
|
|
583
|
+
const y = Math.round( ( position.getY( i ) - min.y ) * scaleY );
|
|
584
|
+
const z = Math.round( ( position.getZ( i ) - min.z ) * scaleZ );
|
|
585
|
+
|
|
586
|
+
let slot = ( Math.imul( x, 73856093 ) ^ Math.imul( y, 19349663 ) ^ Math.imul( z, 83492791 ) ) & vertexMask;
|
|
587
|
+
|
|
588
|
+
while ( vertexSlots[ slot ] !== - 1 && ( vertexKeys[ slot * 3 ] !== x || vertexKeys[ slot * 3 + 1 ] !== y || vertexKeys[ slot * 3 + 2 ] !== z ) ) slot = ( slot + 1 ) & vertexMask;
|
|
589
|
+
|
|
590
|
+
if ( vertexSlots[ slot ] === - 1 ) {
|
|
591
|
+
|
|
592
|
+
vertexSlots[ slot ] = vertexCount ++;
|
|
593
|
+
vertexKeys[ slot * 3 ] = x;
|
|
594
|
+
vertexKeys[ slot * 3 + 1 ] = y;
|
|
595
|
+
vertexKeys[ slot * 3 + 2 ] = z;
|
|
596
|
+
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
vertexIds[ i ] = vertexSlots[ slot ];
|
|
600
|
+
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const edgeMask = MathUtils.ceilPowerOfTwo( Math.max( count, 1 ) * 2 ) - 1;
|
|
604
|
+
const edgeKeys = new Int32Array( ( edgeMask + 1 ) * 2 ).fill( - 1 );
|
|
605
|
+
const edgeParity = new Uint8Array( edgeMask + 1 );
|
|
606
|
+
let openEdges = 0;
|
|
607
|
+
|
|
608
|
+
const toggleEdge = ( a, b ) => {
|
|
609
|
+
|
|
610
|
+
if ( a > b ) {
|
|
611
|
+
|
|
612
|
+
const t = a; a = b; b = t;
|
|
613
|
+
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
let slot = ( Math.imul( a, 73856093 ) ^ Math.imul( b, 19349663 ) ) & edgeMask;
|
|
617
|
+
|
|
618
|
+
while ( edgeKeys[ slot * 2 ] !== - 1 && ( edgeKeys[ slot * 2 ] !== a || edgeKeys[ slot * 2 + 1 ] !== b ) ) slot = ( slot + 1 ) & edgeMask;
|
|
619
|
+
|
|
620
|
+
edgeKeys[ slot * 2 ] = a;
|
|
621
|
+
edgeKeys[ slot * 2 + 1 ] = b;
|
|
622
|
+
edgeParity[ slot ] ^= 1;
|
|
623
|
+
openEdges += edgeParity[ slot ] === 1 ? 1 : - 1;
|
|
624
|
+
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
for ( let i = 0; i + 2 < count; i += 3 ) {
|
|
628
|
+
|
|
629
|
+
const a = vertexIds[ indices !== null ? indices[ i ] : i ];
|
|
630
|
+
const b = vertexIds[ indices !== null ? indices[ i + 1 ] : i + 1 ];
|
|
631
|
+
const c = vertexIds[ indices !== null ? indices[ i + 2 ] : i + 2 ];
|
|
632
|
+
|
|
633
|
+
if ( a === b || b === c || c === a ) continue;
|
|
634
|
+
|
|
635
|
+
toggleEdge( a, b );
|
|
636
|
+
toggleEdge( b, c );
|
|
637
|
+
toggleEdge( c, a );
|
|
638
|
+
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
return openEdges === 0;
|
|
642
|
+
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Returns `true` if the triangles of the given closed geometry face outwards (positive signed volume).
|
|
647
|
+
*
|
|
648
|
+
* @private
|
|
649
|
+
*/
|
|
650
|
+
function facesOutwards( geometry ) {
|
|
651
|
+
|
|
652
|
+
const position = geometry.getAttribute( 'position' );
|
|
653
|
+
const index = geometry.index;
|
|
654
|
+
const indices = index !== null ? index.array : null;
|
|
655
|
+
const count = index !== null ? index.count : position.count;
|
|
656
|
+
|
|
657
|
+
_box.min.fromBufferAttribute( position, 0 );
|
|
658
|
+
|
|
659
|
+
let volume = 0;
|
|
660
|
+
|
|
661
|
+
for ( let i = 0; i + 2 < count; i += 3 ) {
|
|
662
|
+
|
|
663
|
+
_va.fromBufferAttribute( position, indices !== null ? indices[ i ] : i ).sub( _box.min );
|
|
664
|
+
_vb.fromBufferAttribute( position, indices !== null ? indices[ i + 1 ] : i + 1 ).sub( _box.min );
|
|
665
|
+
_vc.fromBufferAttribute( position, indices !== null ? indices[ i + 2 ] : i + 2 ).sub( _box.min );
|
|
666
|
+
|
|
667
|
+
volume += _va.dot( _vb.cross( _vc ) );
|
|
668
|
+
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return volume > 0;
|
|
672
|
+
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Marks the sub-voxels between pairs of surface crossings along each sub-voxel column in x.
|
|
677
|
+
*
|
|
678
|
+
* @private
|
|
679
|
+
*/
|
|
680
|
+
function fillInterior( geometry, matrix, boundsMin, voxelSize, gridSize, target ) {
|
|
681
|
+
|
|
682
|
+
const position = geometry.getAttribute( 'position' );
|
|
683
|
+
const index = geometry.index;
|
|
684
|
+
const count = index !== null ? index.count : position.count;
|
|
685
|
+
|
|
686
|
+
const invSubVoxel = 2 / voxelSize;
|
|
687
|
+
const columnsY = gridSize.y * 2, columnsZ = gridSize.z * 2, length = gridSize.x * 2;
|
|
688
|
+
|
|
689
|
+
_columns.clear();
|
|
690
|
+
|
|
691
|
+
for ( let i = 0; i + 2 < count; i += 3 ) {
|
|
692
|
+
|
|
693
|
+
const a = _va.fromBufferAttribute( position, index !== null ? index.getX( i ) : i ).applyMatrix4( matrix ).sub( boundsMin ).multiplyScalar( invSubVoxel );
|
|
694
|
+
let b = _vb.fromBufferAttribute( position, index !== null ? index.getX( i + 1 ) : i + 1 ).applyMatrix4( matrix ).sub( boundsMin ).multiplyScalar( invSubVoxel );
|
|
695
|
+
let c = _vc.fromBufferAttribute( position, index !== null ? index.getX( i + 2 ) : i + 2 ).applyMatrix4( matrix ).sub( boundsMin ).multiplyScalar( invSubVoxel );
|
|
696
|
+
|
|
697
|
+
const area = edgeFunction( a, b, c.y, c.z );
|
|
698
|
+
|
|
699
|
+
if ( area === 0 ) continue;
|
|
700
|
+
|
|
701
|
+
if ( area < 0 ) {
|
|
702
|
+
|
|
703
|
+
const t = b; b = c; c = t;
|
|
704
|
+
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
const j0 = Math.max( Math.ceil( Math.min( a.y, b.y, c.y ) - 0.5 ), 0 );
|
|
708
|
+
const j1 = Math.min( Math.floor( Math.max( a.y, b.y, c.y ) - 0.5 ), columnsY - 1 );
|
|
709
|
+
const k0 = Math.max( Math.ceil( Math.min( a.z, b.z, c.z ) - 0.5 ), 0 );
|
|
710
|
+
const k1 = Math.min( Math.floor( Math.max( a.z, b.z, c.z ) - 0.5 ), columnsZ - 1 );
|
|
711
|
+
|
|
712
|
+
for ( let k = k0; k <= k1; k ++ ) {
|
|
713
|
+
|
|
714
|
+
for ( let j = j0; j <= j1; j ++ ) {
|
|
715
|
+
|
|
716
|
+
const y = j + 0.5, z = k + 0.5;
|
|
717
|
+
|
|
718
|
+
const wa = edgeFunction( b, c, y, z );
|
|
719
|
+
const wb = edgeFunction( c, a, y, z );
|
|
720
|
+
const wc = edgeFunction( a, b, y, z );
|
|
721
|
+
|
|
722
|
+
if ( isInside( wa, b, c ) && isInside( wb, c, a ) && isInside( wc, a, b ) ) {
|
|
723
|
+
|
|
724
|
+
const column = j + k * columnsY;
|
|
725
|
+
let crossings = _columns.get( column );
|
|
726
|
+
|
|
727
|
+
if ( crossings === undefined ) {
|
|
728
|
+
|
|
729
|
+
crossings = [];
|
|
730
|
+
_columns.set( column, crossings );
|
|
731
|
+
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
crossings.push( ( wa * a.x + wb * b.x + wc * c.x ) / ( wa + wb + wc ) );
|
|
735
|
+
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
for ( const [ column, crossings ] of _columns ) {
|
|
745
|
+
|
|
746
|
+
if ( crossings.length % 2 !== 0 ) continue;
|
|
747
|
+
|
|
748
|
+
crossings.sort( ( p, q ) => p - q );
|
|
749
|
+
|
|
750
|
+
const j = column % columnsY, k = ( column - j ) / columnsY;
|
|
751
|
+
const offset = gridSize.x * ( ( j >> 1 ) + gridSize.y * ( k >> 1 ) );
|
|
752
|
+
const bitsYZ = ( ( j & 1 ) << 1 ) | ( ( k & 1 ) << 2 );
|
|
753
|
+
|
|
754
|
+
for ( let n = 0; n < crossings.length; n += 2 ) {
|
|
755
|
+
|
|
756
|
+
const i0 = Math.max( Math.ceil( crossings[ n ] - 0.5 ), 0 );
|
|
757
|
+
const i1 = Math.min( Math.ceil( crossings[ n + 1 ] - 0.5 ), length );
|
|
758
|
+
|
|
759
|
+
for ( let i = i0; i < i1; i ++ ) target[ offset + ( i >> 1 ) ] |= 1 << ( ( i & 1 ) | bitsYZ );
|
|
760
|
+
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Edge function of the edge from `a` to `b` at the given point in the yz plane. As in the watertight
|
|
769
|
+
* ray/triangle test, the vertices are taken relative to the point, so a shared edge evaluates exactly
|
|
770
|
+
* opposite for both of its triangles.
|
|
771
|
+
*
|
|
772
|
+
* @private
|
|
773
|
+
*/
|
|
774
|
+
function edgeFunction( a, b, y, z ) {
|
|
775
|
+
|
|
776
|
+
return ( a.y - y ) * ( b.z - z ) - ( a.z - z ) * ( b.y - y );
|
|
777
|
+
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Inside test for an edge function value. Points on an edge belong to one triangle only (top-left rule).
|
|
782
|
+
*
|
|
783
|
+
* @private
|
|
784
|
+
*/
|
|
785
|
+
function isInside( w, a, b ) {
|
|
786
|
+
|
|
787
|
+
if ( w !== 0 ) return w > 0;
|
|
788
|
+
|
|
789
|
+
const dz = b.z - a.z;
|
|
790
|
+
|
|
791
|
+
return dz < 0 || ( dz === 0 && b.y > a.y );
|
|
792
|
+
|
|
793
|
+
}
|